Add back the D3D9 code from before the April 2014 code dump.
Bug 22533227
Change-Id: Ib669fcd6a644c79b3a9e8f5dcf7da278d75cefef
Reviewed-on: https://swiftshader-review.googlesource.com/3730
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
diff --git a/src/D3D9/Capabilities.cpp b/src/D3D9/Capabilities.cpp
new file mode 100644
index 0000000..d6f3cf4
--- /dev/null
+++ b/src/D3D9/Capabilities.cpp
@@ -0,0 +1,417 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Capabilities.hpp"
+
+#include "Main/Config.hpp"
+
+namespace D3D9
+{
+ bool Capabilities::Surface::RenderTarget::NULL_ = true;
+ bool Capabilities::Surface::RenderTarget::R8G8B8 = false;
+ bool Capabilities::Surface::RenderTarget::R5G6B5 = true;
+ bool Capabilities::Surface::RenderTarget::X1R5G5B5 = true;
+ bool Capabilities::Surface::RenderTarget::A1R5G5B5 = true;
+ bool Capabilities::Surface::RenderTarget::A4R4G4B4 = true;
+ bool Capabilities::Surface::RenderTarget::R3G3B2 = false;
+ bool Capabilities::Surface::RenderTarget::A8R3G3B2 = false;
+ bool Capabilities::Surface::RenderTarget::X4R4G4B4 = true;
+ bool Capabilities::Surface::RenderTarget::A8R8G8B8 = true;
+ bool Capabilities::Surface::RenderTarget::X8R8G8B8 = true;
+ bool Capabilities::Surface::RenderTarget::A8B8G8R8 = true;
+ bool Capabilities::Surface::RenderTarget::X8B8G8R8 = true;
+ bool Capabilities::Surface::RenderTarget::G16R16 = true;
+ bool Capabilities::Surface::RenderTarget::A2B10G10R10 = true;
+ bool Capabilities::Surface::RenderTarget::A2R10G10B10 = true;
+ bool Capabilities::Surface::RenderTarget::A16B16G16R16 = true;
+ bool Capabilities::Surface::RenderTarget::R16F = true;
+ bool Capabilities::Surface::RenderTarget::G16R16F = true;
+ bool Capabilities::Surface::RenderTarget::A16B16G16R16F = true;
+ bool Capabilities::Surface::RenderTarget::R32F = true;
+ bool Capabilities::Surface::RenderTarget::G32R32F = true;
+ bool Capabilities::Surface::RenderTarget::A32B32G32R32F = true;
+
+ bool Capabilities::Surface::DepthStencil::D32 = true;
+ bool Capabilities::Surface::DepthStencil::D24S8 = true;
+ bool Capabilities::Surface::DepthStencil::D24X8 = true;
+ bool Capabilities::Surface::DepthStencil::D16 = true;
+ bool Capabilities::Surface::DepthStencil::D24FS8 = true;
+ bool Capabilities::Surface::DepthStencil::D32F_LOCKABLE = true;
+ bool Capabilities::Surface::DepthStencil::DF24 = true;
+ bool Capabilities::Surface::DepthStencil::DF16 = true;
+ bool Capabilities::Surface::DepthStencil::INTZ = true;
+
+ bool Capabilities::Surface::A8 = true;
+ bool Capabilities::Surface::R5G6B5 = true;
+ bool Capabilities::Surface::X1R5G5B5 = true;
+ bool Capabilities::Surface::A1R5G5B5 = true;
+ bool Capabilities::Surface::A4R4G4B4 = true;
+ bool Capabilities::Surface::R3G3B2 = true;
+ bool Capabilities::Surface::A8R3G3B2 = true;
+ bool Capabilities::Surface::X4R4G4B4 = true;
+ bool Capabilities::Surface::R8G8B8 = true;
+ bool Capabilities::Surface::X8R8G8B8 = true;
+ bool Capabilities::Surface::A8R8G8B8 = true;
+ bool Capabilities::Surface::X8B8G8R8 = true;
+ bool Capabilities::Surface::A8B8G8R8 = true;
+ bool Capabilities::Surface::P8 = false;
+ bool Capabilities::Surface::A8P8 = false;
+ bool Capabilities::Surface::G16R16 = true;
+ bool Capabilities::Surface::A2R10G10B10 = true;
+ bool Capabilities::Surface::A2B10G10R10 = true;
+ bool Capabilities::Surface::A16B16G16R16 = true;
+ bool Capabilities::Surface::DXT1 = S3TC_SUPPORT;
+ bool Capabilities::Surface::DXT2 = S3TC_SUPPORT;
+ bool Capabilities::Surface::DXT3 = S3TC_SUPPORT;
+ bool Capabilities::Surface::DXT4 = S3TC_SUPPORT;
+ bool Capabilities::Surface::DXT5 = S3TC_SUPPORT;
+ bool Capabilities::Surface::ATI1 = S3TC_SUPPORT;
+ bool Capabilities::Surface::ATI2 = S3TC_SUPPORT;
+ bool Capabilities::Surface::R16F = true;
+ bool Capabilities::Surface::G16R16F = true;
+ bool Capabilities::Surface::A16B16G16R16F = true;
+ bool Capabilities::Surface::R32F = true;
+ bool Capabilities::Surface::G32R32F = true;
+ bool Capabilities::Surface::A32B32G32R32F = true;
+ bool Capabilities::Surface::V8U8 = true;
+ bool Capabilities::Surface::L6V5U5 = true;
+ bool Capabilities::Surface::X8L8V8U8 = true;
+ bool Capabilities::Surface::Q8W8V8U8 = true;
+ bool Capabilities::Surface::V16U16 = true;
+ bool Capabilities::Surface::A2W10V10U10 = true;
+ bool Capabilities::Surface::Q16W16V16U16 = true;
+ bool Capabilities::Surface::L8 = true;
+ bool Capabilities::Surface::A4L4 = true;
+ bool Capabilities::Surface::L16 = true;
+ bool Capabilities::Surface::A8L8 = true;
+ bool Capabilities::Surface::NVDB = false;
+ bool Capabilities::Surface::ATOC = true;
+
+ bool Capabilities::Volume::A8 = true;
+ bool Capabilities::Volume::R5G6B5 = true;
+ bool Capabilities::Volume::X1R5G5B5 = true;
+ bool Capabilities::Volume::A1R5G5B5 = true;
+ bool Capabilities::Volume::A4R4G4B4 = true;
+ bool Capabilities::Volume::R3G3B2 = true;
+ bool Capabilities::Volume::A8R3G3B2 = true;
+ bool Capabilities::Volume::X4R4G4B4 = true;
+ bool Capabilities::Volume::R8G8B8 = false;
+ bool Capabilities::Volume::X8R8G8B8 = true;
+ bool Capabilities::Volume::A8R8G8B8 = true;
+ bool Capabilities::Volume::X8B8G8R8 = true;
+ bool Capabilities::Volume::A8B8G8R8 = true;
+ bool Capabilities::Volume::P8 = false;
+ bool Capabilities::Volume::A8P8 = false;
+ bool Capabilities::Volume::G16R16 = true;
+ bool Capabilities::Volume::A2R10G10B10 = true;
+ bool Capabilities::Volume::A2B10G10R10 = true;
+ bool Capabilities::Volume::A16B16G16R16 = true;
+ bool Capabilities::Volume::DXT1 = S3TC_SUPPORT;
+ bool Capabilities::Volume::DXT2 = S3TC_SUPPORT;
+ bool Capabilities::Volume::DXT3 = S3TC_SUPPORT;
+ bool Capabilities::Volume::DXT4 = S3TC_SUPPORT;
+ bool Capabilities::Volume::DXT5 = S3TC_SUPPORT;
+ bool Capabilities::Volume::ATI1 = S3TC_SUPPORT;
+ bool Capabilities::Volume::ATI2 = S3TC_SUPPORT;
+ bool Capabilities::Volume::R16F = true;
+ bool Capabilities::Volume::G16R16F = true;
+ bool Capabilities::Volume::A16B16G16R16F = true;
+ bool Capabilities::Volume::R32F = true;
+ bool Capabilities::Volume::G32R32F = true;
+ bool Capabilities::Volume::A32B32G32R32F = true;
+ bool Capabilities::Volume::V8U8 = true;
+ bool Capabilities::Volume::L6V5U5 = true;
+ bool Capabilities::Volume::X8L8V8U8 = true;
+ bool Capabilities::Volume::Q8W8V8U8 = true;
+ bool Capabilities::Volume::V16U16 = true;
+ bool Capabilities::Volume::A2W10V10U10 = true;
+ bool Capabilities::Volume::Q16W16V16U16 = true;
+ bool Capabilities::Volume::L8 = true;
+ bool Capabilities::Volume::A4L4 = true;
+ bool Capabilities::Volume::L16 = true;
+ bool Capabilities::Volume::A8L8 = true;
+
+ bool Capabilities::CubeMap::RenderTarget::NULL_ = true;
+ bool Capabilities::CubeMap::RenderTarget::R8G8B8 = false;
+ bool Capabilities::CubeMap::RenderTarget::R5G6B5 = true;
+ bool Capabilities::CubeMap::RenderTarget::X1R5G5B5 = true;
+ bool Capabilities::CubeMap::RenderTarget::A1R5G5B5 = true;
+ bool Capabilities::CubeMap::RenderTarget::A4R4G4B4 = true;
+ bool Capabilities::CubeMap::RenderTarget::R3G3B2 = false;
+ bool Capabilities::CubeMap::RenderTarget::A8R3G3B2 = false;
+ bool Capabilities::CubeMap::RenderTarget::X4R4G4B4 = true;
+ bool Capabilities::CubeMap::RenderTarget::A8R8G8B8 = true;
+ bool Capabilities::CubeMap::RenderTarget::X8R8G8B8 = true;
+ bool Capabilities::CubeMap::RenderTarget::A8B8G8R8 = true;
+ bool Capabilities::CubeMap::RenderTarget::X8B8G8R8 = true;
+ bool Capabilities::CubeMap::RenderTarget::G16R16 = true;
+ bool Capabilities::CubeMap::RenderTarget::A2B10G10R10 = true;
+ bool Capabilities::CubeMap::RenderTarget::A2R10G10B10 = true;
+ bool Capabilities::CubeMap::RenderTarget::A16B16G16R16 = true;
+ bool Capabilities::CubeMap::RenderTarget::R16F = true;
+ bool Capabilities::CubeMap::RenderTarget::G16R16F = true;
+ bool Capabilities::CubeMap::RenderTarget::A16B16G16R16F = true;
+ bool Capabilities::CubeMap::RenderTarget::R32F = true;
+ bool Capabilities::CubeMap::RenderTarget::G32R32F = true;
+ bool Capabilities::CubeMap::RenderTarget::A32B32G32R32F = true;
+
+ bool Capabilities::CubeMap::DepthStencil::D32 = false;
+ bool Capabilities::CubeMap::DepthStencil::D24S8 = false;
+ bool Capabilities::CubeMap::DepthStencil::D24X8 = false;
+ bool Capabilities::CubeMap::DepthStencil::D16 = false;
+ bool Capabilities::CubeMap::DepthStencil::D24FS8 = false;
+ bool Capabilities::CubeMap::DepthStencil::D32F_LOCKABLE = false;
+ bool Capabilities::CubeMap::DepthStencil::DF24 = false;
+ bool Capabilities::CubeMap::DepthStencil::DF16 = false;
+ bool Capabilities::CubeMap::DepthStencil::INTZ = false;
+
+ bool Capabilities::CubeMap::A8 = true;
+ bool Capabilities::CubeMap::R5G6B5 = true;
+ bool Capabilities::CubeMap::X1R5G5B5 = true;
+ bool Capabilities::CubeMap::A1R5G5B5 = true;
+ bool Capabilities::CubeMap::A4R4G4B4 = true;
+ bool Capabilities::CubeMap::R3G3B2 = true;
+ bool Capabilities::CubeMap::A8R3G3B2 = true;
+ bool Capabilities::CubeMap::X4R4G4B4 = true;
+ bool Capabilities::CubeMap::R8G8B8 = false;
+ bool Capabilities::CubeMap::X8R8G8B8 = true;
+ bool Capabilities::CubeMap::A8R8G8B8 = true;
+ bool Capabilities::CubeMap::X8B8G8R8 = true;
+ bool Capabilities::CubeMap::A8B8G8R8 = true;
+ bool Capabilities::CubeMap::P8 = false;
+ bool Capabilities::CubeMap::A8P8 = false;
+ bool Capabilities::CubeMap::G16R16 = true;
+ bool Capabilities::CubeMap::A2R10G10B10 = true;
+ bool Capabilities::CubeMap::A2B10G10R10 = true;
+ bool Capabilities::CubeMap::A16B16G16R16 = true;
+ bool Capabilities::CubeMap::DXT1 = S3TC_SUPPORT;
+ bool Capabilities::CubeMap::DXT2 = S3TC_SUPPORT;
+ bool Capabilities::CubeMap::DXT3 = S3TC_SUPPORT;
+ bool Capabilities::CubeMap::DXT4 = S3TC_SUPPORT;
+ bool Capabilities::CubeMap::DXT5 = S3TC_SUPPORT;
+ bool Capabilities::CubeMap::ATI1 = S3TC_SUPPORT;
+ bool Capabilities::CubeMap::ATI2 = S3TC_SUPPORT;
+ bool Capabilities::CubeMap::R16F = true;
+ bool Capabilities::CubeMap::G16R16F = true;
+ bool Capabilities::CubeMap::A16B16G16R16F = true;
+ bool Capabilities::CubeMap::R32F = true;
+ bool Capabilities::CubeMap::G32R32F = true;
+ bool Capabilities::CubeMap::A32B32G32R32F = true;
+ bool Capabilities::CubeMap::V8U8 = true;
+ bool Capabilities::CubeMap::L6V5U5 = true;
+ bool Capabilities::CubeMap::X8L8V8U8 = true;
+ bool Capabilities::CubeMap::Q8W8V8U8 = true;
+ bool Capabilities::CubeMap::V16U16 = true;
+ bool Capabilities::CubeMap::A2W10V10U10 = true;
+ bool Capabilities::CubeMap::Q16W16V16U16 = true;
+ bool Capabilities::CubeMap::L8 = true;
+ bool Capabilities::CubeMap::A4L4 = true;
+ bool Capabilities::CubeMap::L16 = true;
+ bool Capabilities::CubeMap::A8L8 = true;
+
+ bool Capabilities::VolumeTexture::A8 = true;
+ bool Capabilities::VolumeTexture::R5G6B5 = true;
+ bool Capabilities::VolumeTexture::X1R5G5B5 = true;
+ bool Capabilities::VolumeTexture::A1R5G5B5 = true;
+ bool Capabilities::VolumeTexture::A4R4G4B4 = true;
+ bool Capabilities::VolumeTexture::R3G3B2 = true;
+ bool Capabilities::VolumeTexture::A8R3G3B2 = true;
+ bool Capabilities::VolumeTexture::X4R4G4B4 = true;
+ bool Capabilities::VolumeTexture::R8G8B8 = false;
+ bool Capabilities::VolumeTexture::X8R8G8B8 = true;
+ bool Capabilities::VolumeTexture::A8R8G8B8 = true;
+ bool Capabilities::VolumeTexture::X8B8G8R8 = true;
+ bool Capabilities::VolumeTexture::A8B8G8R8 = true;
+ bool Capabilities::VolumeTexture::P8 = false;
+ bool Capabilities::VolumeTexture::A8P8 = false;
+ bool Capabilities::VolumeTexture::G16R16 = true;
+ bool Capabilities::VolumeTexture::A2R10G10B10 = true;
+ bool Capabilities::VolumeTexture::A2B10G10R10 = true;
+ bool Capabilities::VolumeTexture::A16B16G16R16 = true;
+ bool Capabilities::VolumeTexture::DXT1 = S3TC_SUPPORT;
+ bool Capabilities::VolumeTexture::DXT2 = S3TC_SUPPORT;
+ bool Capabilities::VolumeTexture::DXT3 = S3TC_SUPPORT;
+ bool Capabilities::VolumeTexture::DXT4 = S3TC_SUPPORT;
+ bool Capabilities::VolumeTexture::DXT5 = S3TC_SUPPORT;
+ bool Capabilities::VolumeTexture::ATI1 = S3TC_SUPPORT;
+ bool Capabilities::VolumeTexture::ATI2 = S3TC_SUPPORT;
+ bool Capabilities::VolumeTexture::R16F = true;
+ bool Capabilities::VolumeTexture::G16R16F = true;
+ bool Capabilities::VolumeTexture::A16B16G16R16F = true;
+ bool Capabilities::VolumeTexture::R32F = true;
+ bool Capabilities::VolumeTexture::G32R32F = true;
+ bool Capabilities::VolumeTexture::A32B32G32R32F = true;
+ bool Capabilities::VolumeTexture::V8U8 = true;
+ bool Capabilities::VolumeTexture::L6V5U5 = true;
+ bool Capabilities::VolumeTexture::X8L8V8U8 = true;
+ bool Capabilities::VolumeTexture::Q8W8V8U8 = true;
+ bool Capabilities::VolumeTexture::V16U16 = true;
+ bool Capabilities::VolumeTexture::A2W10V10U10 = true;
+ bool Capabilities::VolumeTexture::Q16W16V16U16 = true;
+ bool Capabilities::VolumeTexture::L8 = true;
+ bool Capabilities::VolumeTexture::A4L4 = true;
+ bool Capabilities::VolumeTexture::L16 = true;
+ bool Capabilities::VolumeTexture::A8L8 = true;
+
+ bool Capabilities::Texture::RenderTarget::NULL_ = true;
+ bool Capabilities::Texture::RenderTarget::R8G8B8 = false;
+ bool Capabilities::Texture::RenderTarget::R5G6B5 = true;
+ bool Capabilities::Texture::RenderTarget::X1R5G5B5 = true;
+ bool Capabilities::Texture::RenderTarget::A1R5G5B5 = true;
+ bool Capabilities::Texture::RenderTarget::A4R4G4B4 = true;
+ bool Capabilities::Texture::RenderTarget::R3G3B2 = false;
+ bool Capabilities::Texture::RenderTarget::A8R3G3B2 = false;
+ bool Capabilities::Texture::RenderTarget::X4R4G4B4 = true;
+ bool Capabilities::Texture::RenderTarget::A8R8G8B8 = true;
+ bool Capabilities::Texture::RenderTarget::X8R8G8B8 = true;
+ bool Capabilities::Texture::RenderTarget::A8B8G8R8 = true;
+ bool Capabilities::Texture::RenderTarget::X8B8G8R8 = true;
+ bool Capabilities::Texture::RenderTarget::G16R16 = true;
+ bool Capabilities::Texture::RenderTarget::A2B10G10R10 = true;
+ bool Capabilities::Texture::RenderTarget::A2R10G10B10 = true;
+ bool Capabilities::Texture::RenderTarget::A16B16G16R16 = true;
+ bool Capabilities::Texture::RenderTarget::R16F = true;
+ bool Capabilities::Texture::RenderTarget::G16R16F = true;
+ bool Capabilities::Texture::RenderTarget::A16B16G16R16F = true;
+ bool Capabilities::Texture::RenderTarget::R32F = true;
+ bool Capabilities::Texture::RenderTarget::G32R32F = true;
+ bool Capabilities::Texture::RenderTarget::A32B32G32R32F = true;
+
+ bool Capabilities::Texture::DepthStencil::D32 = true;
+ bool Capabilities::Texture::DepthStencil::D24S8 = true;
+ bool Capabilities::Texture::DepthStencil::D24X8 = true;
+ bool Capabilities::Texture::DepthStencil::D16 = true;
+ bool Capabilities::Texture::DepthStencil::D24FS8 = true;
+ bool Capabilities::Texture::DepthStencil::D32F_LOCKABLE = true;
+ bool Capabilities::Texture::DepthStencil::DF24 = true;
+ bool Capabilities::Texture::DepthStencil::DF16 = true;
+ bool Capabilities::Texture::DepthStencil::INTZ = true;
+
+ bool Capabilities::Texture::NULL_ = true;
+ bool Capabilities::Texture::A8 = true;
+ bool Capabilities::Texture::R5G6B5 = true;
+ bool Capabilities::Texture::X1R5G5B5 = true;
+ bool Capabilities::Texture::A1R5G5B5 = true;
+ bool Capabilities::Texture::A4R4G4B4 = true;
+ bool Capabilities::Texture::R3G3B2 = true;
+ bool Capabilities::Texture::A8R3G3B2 = true;
+ bool Capabilities::Texture::X4R4G4B4 = true;
+ bool Capabilities::Texture::R8G8B8 = false;
+ bool Capabilities::Texture::X8R8G8B8 = true;
+ bool Capabilities::Texture::A8R8G8B8 = true;
+ bool Capabilities::Texture::X8B8G8R8 = true;
+ bool Capabilities::Texture::A8B8G8R8 = true;
+ bool Capabilities::Texture::P8 = false;
+ bool Capabilities::Texture::A8P8 = false;
+ bool Capabilities::Texture::G16R16 = true;
+ bool Capabilities::Texture::A2R10G10B10 = true;
+ bool Capabilities::Texture::A2B10G10R10 = true;
+ bool Capabilities::Texture::A16B16G16R16 = true;
+ bool Capabilities::Texture::DXT1 = S3TC_SUPPORT;
+ bool Capabilities::Texture::DXT2 = S3TC_SUPPORT;
+ bool Capabilities::Texture::DXT3 = S3TC_SUPPORT;
+ bool Capabilities::Texture::DXT4 = S3TC_SUPPORT;
+ bool Capabilities::Texture::DXT5 = S3TC_SUPPORT;
+ bool Capabilities::Texture::ATI1 = S3TC_SUPPORT;
+ bool Capabilities::Texture::ATI2 = S3TC_SUPPORT;
+ bool Capabilities::Texture::R16F = true;
+ bool Capabilities::Texture::G16R16F = true;
+ bool Capabilities::Texture::A16B16G16R16F = true;
+ bool Capabilities::Texture::R32F = true;
+ bool Capabilities::Texture::G32R32F = true;
+ bool Capabilities::Texture::A32B32G32R32F = true;
+ bool Capabilities::Texture::V8U8 = true;
+ bool Capabilities::Texture::L6V5U5 = true;
+ bool Capabilities::Texture::X8L8V8U8 = true;
+ bool Capabilities::Texture::Q8W8V8U8 = true;
+ bool Capabilities::Texture::V16U16 = true;
+ bool Capabilities::Texture::A2W10V10U10 = true;
+ bool Capabilities::Texture::Q16W16V16U16 = true;
+ bool Capabilities::Texture::L8 = true;
+ bool Capabilities::Texture::A4L4 = true;
+ bool Capabilities::Texture::L16 = true;
+ bool Capabilities::Texture::A8L8 = true;
+ bool Capabilities::Texture::D32 = true;
+ bool Capabilities::Texture::D24S8 = true;
+ bool Capabilities::Texture::D24X8 = true;
+ bool Capabilities::Texture::D16 = true;
+ bool Capabilities::Texture::D24FS8 = true;
+ bool Capabilities::Texture::D32F_LOCKABLE = true;
+ bool Capabilities::Texture::DF24 = true;
+ bool Capabilities::Texture::DF16 = true;
+ bool Capabilities::Texture::INTZ = true;
+
+ bool Capabilities::isSRGBreadable(D3DFORMAT format)
+ {
+ // Keep in sync with Surface::isSRGBreadable
+ switch(format)
+ {
+ case D3DFMT_L8:
+ case D3DFMT_A8L8:
+ case D3DFMT_R8G8B8:
+ case D3DFMT_A8R8G8B8:
+ case D3DFMT_X8R8G8B8:
+ case D3DFMT_A8B8G8R8:
+ case D3DFMT_X8B8G8R8:
+ case D3DFMT_R5G6B5:
+ case D3DFMT_X1R5G5B5:
+ case D3DFMT_A1R5G5B5:
+ case D3DFMT_A4R4G4B4:
+ case D3DFMT_DXT1:
+ case D3DFMT_DXT2:
+ case D3DFMT_DXT3:
+ case D3DFMT_DXT4:
+ case D3DFMT_DXT5:
+ case D3DFMT_ATI1:
+ case D3DFMT_ATI2:
+ return true;
+ default:
+ return false;
+ }
+
+ return false;
+ }
+
+ bool Capabilities::isSRGBwritable(D3DFORMAT format)
+ {
+ // Keep in sync with Surface::isSRGBwritable
+ switch(format)
+ {
+ case D3DFMT_NULL:
+ case D3DFMT_A8R8G8B8:
+ case D3DFMT_X8R8G8B8:
+ case D3DFMT_A8B8G8R8:
+ case D3DFMT_X8B8G8R8:
+ case D3DFMT_R5G6B5:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ unsigned int pixelShaderVersionX = D3DPS_VERSION(3, 0);
+ unsigned int vertexShaderVersionX = D3DVS_VERSION(3, 0);
+
+ unsigned long pixelShaderArbitrarySwizzle = D3DPS20CAPS_ARBITRARYSWIZZLE;
+ unsigned long pixelShaderGradientInstructions = D3DPS20CAPS_GRADIENTINSTRUCTIONS;
+ unsigned long pixelShaderPredication = D3DPS20CAPS_PREDICATION;
+ unsigned long pixelShaderNoDependentReadLimit = D3DPS20CAPS_NODEPENDENTREADLIMIT;
+ unsigned long pixelShaderNoTexInstructionLimit = D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
+
+ unsigned long pixelShaderDynamicFlowControlDepth = D3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH;
+ unsigned long pixelShaderStaticFlowControlDepth = D3DPS20_MAX_STATICFLOWCONTROLDEPTH;
+
+ unsigned long vertexShaderPredication = D3DVS20CAPS_PREDICATION;
+ unsigned long vertexShaderDynamicFlowControlDepth = D3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH;
+
+ unsigned int textureMemory = 256 * 1024 * 1024;
+ unsigned int maxAnisotropy = 16;
+}
diff --git a/src/D3D9/Capabilities.hpp b/src/D3D9/Capabilities.hpp
new file mode 100644
index 0000000..dc16fce
--- /dev/null
+++ b/src/D3D9/Capabilities.hpp
@@ -0,0 +1,467 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Capabilities_hpp
+#define D3D9_Capabilities_hpp
+
+#include <d3d9.h>
+
+namespace D3D9
+{
+ enum
+ {
+ D3DFMT_ATI1 = MAKEFOURCC('A', 'T', 'I', '1'),
+ D3DFMT_ATI2 = MAKEFOURCC('A', 'T', 'I', '2'),
+ D3DFMT_INST = MAKEFOURCC('I', 'N', 'S', 'T'),
+ D3DFMT_DF24 = MAKEFOURCC('D', 'F', '2', '4'),
+ D3DFMT_DF16 = MAKEFOURCC('D', 'F', '1', '6'),
+ D3DFMT_NULL = MAKEFOURCC('N', 'U', 'L', 'L'),
+ D3DFMT_GET4 = MAKEFOURCC('G', 'E', 'T', '4'),
+ D3DFMT_GET1 = MAKEFOURCC('G', 'E', 'T', '1'),
+ D3DFMT_NVDB = MAKEFOURCC('N', 'V', 'D', 'B'),
+ D3DFMT_A2M1 = MAKEFOURCC('A', '2', 'M', '1'),
+ D3DFMT_A2M0 = MAKEFOURCC('A', '2', 'M', '0'),
+ D3DFMT_ATOC = MAKEFOURCC('A', 'T', 'O', 'C'),
+ D3DFMT_INTZ = MAKEFOURCC('I', 'N', 'T', 'Z')
+ };
+
+ struct Capabilities
+ {
+ struct Surface
+ {
+ struct RenderTarget
+ {
+ static bool NULL_;
+ static bool R8G8B8;
+ static bool R5G6B5;
+ static bool X1R5G5B5;
+ static bool A1R5G5B5;
+ static bool A4R4G4B4;
+ static bool R3G3B2;
+ static bool A8R3G3B2;
+ static bool X4R4G4B4;
+ static bool A8R8G8B8;
+ static bool X8R8G8B8;
+ static bool A8B8G8R8;
+ static bool X8B8G8R8;
+ // Integer HDR formats
+ static bool G16R16;
+ static bool A2B10G10R10;
+ static bool A2R10G10B10;
+ static bool A16B16G16R16;
+ // Floating-point formats
+ static bool R16F;
+ static bool G16R16F;
+ static bool A16B16G16R16F;
+ static bool R32F;
+ static bool G32R32F;
+ static bool A32B32G32R32F;
+ };
+
+ struct DepthStencil
+ {
+ static bool D32;
+ static bool D24S8;
+ static bool D24X8;
+ static bool D16;
+ static bool D24FS8;
+ static bool D32F_LOCKABLE;
+ static bool DF24;
+ static bool DF16;
+ static bool INTZ;
+ };
+
+ static bool A8;
+ static bool R5G6B5;
+ static bool X1R5G5B5;
+ static bool A1R5G5B5;
+ static bool A4R4G4B4;
+ static bool R3G3B2;
+ static bool A8R3G3B2;
+ static bool X4R4G4B4;
+ static bool R8G8B8;
+ static bool X8R8G8B8;
+ static bool A8R8G8B8;
+ static bool A8B8G8R8;
+ static bool X8B8G8R8;
+ // Paletted formats
+ static bool P8;
+ static bool A8P8;
+ // Integer HDR formats
+ static bool G16R16;
+ static bool A2R10G10B10;
+ static bool A2B10G10R10;
+ static bool A16B16G16R16;
+ // Compressed formats
+ static bool DXT1;
+ static bool DXT2;
+ static bool DXT3;
+ static bool DXT4;
+ static bool DXT5;
+ static bool ATI1;
+ static bool ATI2;
+ // Floating-point formats
+ static bool R16F;
+ static bool G16R16F;
+ static bool A16B16G16R16F;
+ static bool R32F;
+ static bool G32R32F;
+ static bool A32B32G32R32F;
+ // Bump map formats
+ static bool V8U8;
+ static bool L6V5U5;
+ static bool X8L8V8U8;
+ static bool Q8W8V8U8;
+ static bool V16U16;
+ static bool A2W10V10U10;
+ static bool Q16W16V16U16;
+ // Luminance formats
+ static bool L8;
+ static bool A4L4;
+ static bool L16;
+ static bool A8L8;
+ // Depth Bounds Test
+ static bool NVDB;
+ // Transparency anti-aliasing
+ static bool ATOC;
+ };
+
+ struct Volume
+ {
+ static bool A8;
+ static bool R5G6B5;
+ static bool X1R5G5B5;
+ static bool A1R5G5B5;
+ static bool A4R4G4B4;
+ static bool R3G3B2;
+ static bool A8R3G3B2;
+ static bool X4R4G4B4;
+ static bool R8G8B8;
+ static bool X8R8G8B8;
+ static bool A8R8G8B8;
+ static bool A8B8G8R8;
+ static bool X8B8G8R8;
+ // Paletted formats
+ static bool P8;
+ static bool A8P8;
+ // Integer HDR formats
+ static bool G16R16;
+ static bool A2R10G10B10;
+ static bool A2B10G10R10;
+ static bool A16B16G16R16;
+ // Compressed formats
+ static bool DXT1;
+ static bool DXT2;
+ static bool DXT3;
+ static bool DXT4;
+ static bool DXT5;
+ static bool ATI1;
+ static bool ATI2;
+ // Floating-point formats
+ static bool R16F;
+ static bool G16R16F;
+ static bool A16B16G16R16F;
+ static bool R32F;
+ static bool G32R32F;
+ static bool A32B32G32R32F;
+ // Bump map formats
+ static bool V8U8;
+ static bool L6V5U5;
+ static bool X8L8V8U8;
+ static bool Q8W8V8U8;
+ static bool V16U16;
+ static bool A2W10V10U10;
+ static bool Q16W16V16U16;
+ // Luminance formats
+ static bool L8;
+ static bool A4L4;
+ static bool L16;
+ static bool A8L8;
+ };
+
+ struct CubeMap
+ {
+ struct RenderTarget
+ {
+ static bool NULL_;
+ static bool R8G8B8;
+ static bool R5G6B5;
+ static bool X1R5G5B5;
+ static bool A1R5G5B5;
+ static bool A4R4G4B4;
+ static bool R3G3B2;
+ static bool A8R3G3B2;
+ static bool X4R4G4B4;
+ static bool A8R8G8B8;
+ static bool X8R8G8B8;
+ static bool A8B8G8R8;
+ static bool X8B8G8R8;
+ // Integer HDR formats
+ static bool G16R16;
+ static bool A2B10G10R10;
+ static bool A2R10G10B10;
+ static bool A16B16G16R16;
+ // Floating-point formats
+ static bool R16F;
+ static bool G16R16F;
+ static bool A16B16G16R16F;
+ static bool R32F;
+ static bool G32R32F;
+ static bool A32B32G32R32F;
+ };
+
+ struct DepthStencil
+ {
+ static bool D32;
+ static bool D24S8;
+ static bool D24X8;
+ static bool D16;
+ static bool D24FS8;
+ static bool D32F_LOCKABLE;
+ static bool DF24;
+ static bool DF16;
+ static bool INTZ;
+ };
+
+ static bool A8;
+ static bool R5G6B5;
+ static bool X1R5G5B5;
+ static bool A1R5G5B5;
+ static bool A4R4G4B4;
+ static bool R3G3B2;
+ static bool A8R3G3B2;
+ static bool X4R4G4B4;
+ static bool R8G8B8;
+ static bool X8R8G8B8;
+ static bool A8R8G8B8;
+ static bool A8B8G8R8;
+ static bool X8B8G8R8;
+ // Paletted formats
+ static bool P8;
+ static bool A8P8;
+ // Integer HDR formats
+ static bool G16R16;
+ static bool A2R10G10B10;
+ static bool A2B10G10R10;
+ static bool A16B16G16R16;
+ // Compressed formats
+ static bool DXT1;
+ static bool DXT2;
+ static bool DXT3;
+ static bool DXT4;
+ static bool DXT5;
+ static bool ATI1;
+ static bool ATI2;
+ // Floating-point formats
+ static bool R16F;
+ static bool G16R16F;
+ static bool A16B16G16R16F;
+ static bool R32F;
+ static bool G32R32F;
+ static bool A32B32G32R32F;
+ // Bump map formats
+ static bool V8U8;
+ static bool L6V5U5;
+ static bool X8L8V8U8;
+ static bool Q8W8V8U8;
+ static bool V16U16;
+ static bool A2W10V10U10;
+ static bool Q16W16V16U16;
+ // Luminance formats
+ static bool L8;
+ static bool A4L4;
+ static bool L16;
+ static bool A8L8;
+ };
+
+ struct VolumeTexture
+ {
+ static bool A8;
+ static bool R5G6B5;
+ static bool X1R5G5B5;
+ static bool A1R5G5B5;
+ static bool A4R4G4B4;
+ static bool R3G3B2;
+ static bool A8R3G3B2;
+ static bool X4R4G4B4;
+ static bool R8G8B8;
+ static bool X8R8G8B8;
+ static bool A8R8G8B8;
+ static bool A8B8G8R8;
+ static bool X8B8G8R8;
+ // Paletted formats
+ static bool P8;
+ static bool A8P8;
+ // Integer HDR formats
+ static bool G16R16;
+ static bool A2R10G10B10;
+ static bool A2B10G10R10;
+ static bool A16B16G16R16;
+ // Compressed formats
+ static bool DXT1;
+ static bool DXT2;
+ static bool DXT3;
+ static bool DXT4;
+ static bool DXT5;
+ static bool ATI1;
+ static bool ATI2;
+ // Floating-point formats
+ static bool R16F;
+ static bool G16R16F;
+ static bool A16B16G16R16F;
+ static bool R32F;
+ static bool G32R32F;
+ static bool A32B32G32R32F;
+ // Bump map formats
+ static bool V8U8;
+ static bool L6V5U5;
+ static bool X8L8V8U8;
+ static bool Q8W8V8U8;
+ static bool V16U16;
+ static bool A2W10V10U10;
+ static bool Q16W16V16U16;
+ // Luminance formats
+ static bool L8;
+ static bool A4L4;
+ static bool L16;
+ static bool A8L8;
+ };
+
+ struct Texture
+ {
+ struct RenderTarget
+ {
+ static bool NULL_;
+ static bool R8G8B8;
+ static bool R5G6B5;
+ static bool X1R5G5B5;
+ static bool A1R5G5B5;
+ static bool A4R4G4B4;
+ static bool R3G3B2;
+ static bool A8R3G3B2;
+ static bool X4R4G4B4;
+ static bool A8R8G8B8;
+ static bool X8R8G8B8;
+ static bool A8B8G8R8;
+ static bool X8B8G8R8;
+ // Integer HDR formats
+ static bool G16R16;
+ static bool A2B10G10R10;
+ static bool A2R10G10B10;
+ static bool A16B16G16R16;
+ // Floating-point formats
+ static bool R16F;
+ static bool G16R16F;
+ static bool A16B16G16R16F;
+ static bool R32F;
+ static bool G32R32F;
+ static bool A32B32G32R32F;
+ };
+
+ struct DepthStencil
+ {
+ static bool D32;
+ static bool D24S8;
+ static bool D24X8;
+ static bool D16;
+ static bool D24FS8;
+ static bool D32F_LOCKABLE;
+ static bool DF24;
+ static bool DF16;
+ static bool INTZ;
+ };
+
+ static bool NULL_;
+ static bool A8;
+ static bool R5G6B5;
+ static bool X1R5G5B5;
+ static bool A1R5G5B5;
+ static bool A4R4G4B4;
+ static bool R3G3B2;
+ static bool A8R3G3B2;
+ static bool X4R4G4B4;
+ static bool R8G8B8;
+ static bool X8R8G8B8;
+ static bool A8R8G8B8;
+ static bool A8B8G8R8;
+ static bool X8B8G8R8;
+ // Paletted formats
+ static bool P8;
+ static bool A8P8;
+ // Integer HDR formats
+ static bool G16R16;
+ static bool A2R10G10B10;
+ static bool A2B10G10R10;
+ static bool A16B16G16R16;
+ // Compressed formats
+ static bool DXT1;
+ static bool DXT2;
+ static bool DXT3;
+ static bool DXT4;
+ static bool DXT5;
+ static bool ATI1;
+ static bool ATI2;
+ // Floating-point formats
+ static bool R16F;
+ static bool G16R16F;
+ static bool A16B16G16R16F;
+ static bool R32F;
+ static bool G32R32F;
+ static bool A32B32G32R32F;
+ // Bump map formats
+ static bool V8U8;
+ static bool L6V5U5;
+ static bool X8L8V8U8;
+ static bool Q8W8V8U8;
+ static bool V16U16;
+ static bool A2W10V10U10;
+ static bool Q16W16V16U16;
+ // Luminance formats
+ static bool L8;
+ static bool A4L4;
+ static bool L16;
+ static bool A8L8;
+ // Depth formats
+ static bool D32;
+ static bool D24S8;
+ static bool D24X8;
+ static bool D16;
+ static bool D24FS8;
+ static bool D32F_LOCKABLE;
+ static bool DF24;
+ static bool DF16;
+ static bool INTZ;
+ };
+
+ static bool isSRGBreadable(D3DFORMAT format);
+ static bool isSRGBwritable(D3DFORMAT format);
+ };
+
+ extern unsigned int pixelShaderVersionX;
+ extern unsigned int vertexShaderVersionX;
+
+ extern unsigned long pixelShaderArbitrarySwizzle;
+ extern unsigned long pixelShaderGradientInstructions;
+ extern unsigned long pixelShaderPredication;
+ extern unsigned long pixelShaderNoDependentReadLimit;
+ extern unsigned long pixelShaderNoTexInstructionLimit;
+
+ extern unsigned long pixelShaderDynamicFlowControlDepth;
+ extern unsigned long pixelShaderStaticFlowControlDepth;
+
+ extern unsigned long vertexShaderPredication;
+ extern unsigned long vertexShaderDynamicFlowControlDepth;
+
+ extern unsigned int textureMemory;
+ extern unsigned int maxAnisotropy;
+}
+
+#endif // D3D9_Capabilities_hpp
diff --git a/src/D3D9/D3D9.cpp b/src/D3D9/D3D9.cpp
new file mode 100644
index 0000000..9a11bd4
--- /dev/null
+++ b/src/D3D9/D3D9.cpp
@@ -0,0 +1,293 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3D9.hpp"
+#include "Direct3D9Ex.hpp"
+
+#include "Debug.hpp"
+
+#include "resource.h"
+
+#include <stdio.h>
+#include <assert.h>
+
+namespace D3D9
+{
+ class Direct3DShaderValidator9
+ {
+ public:
+ Direct3DShaderValidator9();
+
+ virtual ~Direct3DShaderValidator9();
+
+ virtual int __stdcall ValidateShader(long *shader, long *shader1, long *shader2, long *shader3);
+ virtual int __stdcall ValidateShader2(long *shader);
+ virtual int __stdcall ValidateShader3(long *shader, long *shader1, long *shader2, long *shader3);
+ virtual int __stdcall ValidateShader4(long *shader, long *shader1, long *shader2, long *shader3);
+ virtual int __stdcall ValidateShader5(long *shader, long *shader1, long *shader2);
+ virtual int __stdcall ValidateShader6(long *shader, long *shader1, long *shader2, long *shader3);
+ };
+
+ Direct3DShaderValidator9::Direct3DShaderValidator9()
+ {
+ }
+
+ Direct3DShaderValidator9::~Direct3DShaderValidator9()
+ {
+ }
+
+ int __stdcall Direct3DShaderValidator9::ValidateShader(long *shader, long *shader1, long *shader2, long *shader3) // FIXME
+ {
+ TRACE("");
+
+ UNIMPLEMENTED();
+
+ return true; // FIXME
+ }
+
+ int __stdcall Direct3DShaderValidator9::ValidateShader2(long *shader) // FIXME
+ {
+ TRACE("");
+
+ UNIMPLEMENTED();
+
+ return true; // FIXME
+ }
+
+ int __stdcall Direct3DShaderValidator9::ValidateShader3(long *shader, long *shader1, long *shader2, long *shader3)
+ {
+ TRACE("");
+
+ UNIMPLEMENTED();
+
+ return true; // FIXME
+ }
+
+ int __stdcall Direct3DShaderValidator9::ValidateShader4(long *shader, long *shader1, long *shader2, long *shader3)
+ {
+ TRACE("");
+
+ UNIMPLEMENTED();
+
+ return true; // FIXME
+ }
+
+ int __stdcall Direct3DShaderValidator9::ValidateShader5(long *shader, long *shader1, long *shader2) // FIXME
+ {
+ TRACE("");
+
+ UNIMPLEMENTED();
+
+ return true; // FIXME
+ }
+
+ int __stdcall Direct3DShaderValidator9::ValidateShader6(long *shader, long *shader1, long *shader2, long *shader3) // FIXME
+ {
+ TRACE("");
+
+ UNIMPLEMENTED();
+
+ return true; // FIXME
+ }
+}
+
+using namespace D3D9;
+
+extern "C"
+{
+ HINSTANCE dllInstance = 0;
+
+ int __stdcall DllMain(HINSTANCE instance, unsigned long reason, void *reserved)
+ {
+ #ifndef NDEBUG
+ if(dllInstance == 0)
+ {
+ FILE *file = fopen("debug.txt", "w"); // Clear debug log
+ fclose(file);
+ }
+ #endif
+
+ GTRACE("HINSTANCE instance = 0x%0.8p, unsigned long reason = %d, void *reserved = 0x%0.8p", instance, reason, reserved);
+
+ dllInstance = instance;
+
+ switch(reason)
+ {
+ case DLL_PROCESS_DETACH:
+ break;
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(instance);
+ break;
+ case DLL_THREAD_ATTACH:
+ break;
+ case DLL_THREAD_DETACH:
+ break;
+ default:
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ IDirect3D9 *__stdcall Direct3DCreate9(unsigned int version)
+ {
+ GTRACE("");
+
+ // D3D_SDK_VERSION check
+ if(version != (31 | 0x80000000) && // 9.0a/b DEBUG_INFO
+ version != 31 && // 9.0a/b
+ version != (32 | 0x80000000) && // 9.0c DEBUG_INFO
+ version != 32) // 9.0c
+ {
+ return 0;
+ }
+
+ IDirect3D9 *device = new D3D9::Direct3D9(version, dllInstance);
+
+ if(device)
+ {
+ device->AddRef();
+ }
+
+ return device;
+ }
+
+ HRESULT __stdcall Direct3DCreate9Ex(unsigned int version, IDirect3D9Ex **device)
+ {
+ // D3D_SDK_VERSION check
+ if(version != (31 | 0x80000000) && // 9.0a/b DEBUG_INFO
+ version != 31 && // 9.0a/b
+ version != (32 | 0x80000000) && // 9.0c DEBUG_INFO
+ version != 32) // 9.0c
+ {
+ return NOTAVAILABLE();
+ }
+
+ *device = new D3D9::Direct3D9Ex(version, dllInstance);
+
+ if(device)
+ {
+ (*device)->AddRef();
+ }
+ else
+ {
+ return OUTOFMEMORY();
+ }
+
+ return D3D_OK;
+ }
+
+ int __stdcall CheckFullscreen()
+ {
+ GTRACE("");
+
+ UNIMPLEMENTED();
+
+ return FALSE;
+ }
+
+ int __stdcall D3DPERF_BeginEvent(D3DCOLOR color, const wchar_t *name)
+ {
+ GTRACE("");
+
+ // UNIMPLEMENTED(); // PIX unsupported
+
+ return -1;
+ }
+
+ int __stdcall D3DPERF_EndEvent()
+ {
+ GTRACE("");
+
+ // UNIMPLEMENTED(); // PIX unsupported
+
+ return -1;
+ }
+
+ unsigned long __stdcall D3DPERF_GetStatus()
+ {
+ GTRACE("");
+
+ // UNIMPLEMENTED(); // PIX unsupported
+
+ return 0;
+ }
+
+ int __stdcall D3DPERF_QueryRepeatFrame()
+ {
+ GTRACE("");
+
+ // UNIMPLEMENTED(); // PIX unsupported
+
+ return FALSE;
+ }
+
+ void __stdcall D3DPERF_SetMarker(D3DCOLOR color, const wchar_t *name)
+ {
+ GTRACE("");
+
+ // UNIMPLEMENTED(); // PIX unsupported
+ }
+
+ void __stdcall D3DPERF_SetOptions(unsigned long options)
+ {
+ GTRACE("");
+
+ // UNIMPLEMENTED(); // PIX unsupported
+ }
+
+ void __stdcall D3DPERF_SetRegion(D3DCOLOR color, const wchar_t *name)
+ {
+ GTRACE("");
+
+ // UNIMPLEMENTED(); // PIX unsupported
+ }
+
+ void __cdecl DebugSetLevel(long level)
+ {
+ GTRACE("long level = %d", level);
+
+ // UNIMPLEMENTED(); // Debug output unsupported
+ }
+
+ void __cdecl DebugSetMute(long mute)
+ {
+ GTRACE("long mute = %d", mute);
+
+ // UNIMPLEMENTED(); // Debug output unsupported
+ }
+
+ void *__stdcall Direct3DShaderValidatorCreate9()
+ {
+ GTRACE("");
+
+ // UNIMPLEMENTED();
+
+ return 0;
+
+ // return new D3D9::Direct3DShaderValidator9();
+ }
+
+ void __stdcall PSGPError()
+ {
+ GTRACE("");
+
+ UNIMPLEMENTED();
+ }
+
+ void __stdcall PSGPSampleTexture()
+ {
+ GTRACE("");
+
+ UNIMPLEMENTED();
+ }
+}
diff --git a/src/D3D9/D3D9.rc b/src/D3D9/D3D9.rc
new file mode 100644
index 0000000..a0d69e6
--- /dev/null
+++ b/src/D3D9/D3D9.rc
@@ -0,0 +1,101 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+#include "../Common/Version.h"
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (United States) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "#include ""../Common/Version.h""\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION MAJOR_VERSION,MINOR_VERSION,BUILD_VERSION,BUILD_REVISION
+ PRODUCTVERSION MAJOR_VERSION,MINOR_VERSION,BUILD_VERSION,BUILD_REVISION
+ FILEFLAGSMASK 0x1fL
+#ifdef _DEBUG
+ FILEFLAGS 0x9L
+#else
+ FILEFLAGS 0x8L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "TransGaming"
+ VALUE "FileDescription", "SwiftShader Direct3D 9 Software Renderer"
+ VALUE "FileVersion", VERSION_STRING
+ VALUE "InternalName", "D3D9"
+ VALUE "LegalCopyright", "Copyright (C) 2011 TransGaming Inc."
+ VALUE "OriginalFilename", "d3d9.dll"
+ VALUE "PrivateBuild", REVISION_STRING
+ VALUE "ProductName", "SwiftShader Direct3D 9 Software Renderer"
+ VALUE "ProductVersion", VERSION_STRING
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // English (United States) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/src/D3D9/D3D9.vcproj b/src/D3D9/D3D9.vcproj
new file mode 100644
index 0000000..3d265fd
--- /dev/null
+++ b/src/D3D9/D3D9.vcproj
@@ -0,0 +1,650 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="D3D9"
+ ProjectGUID="{F18D5ABF-CA3A-4B74-BDB2-4A1957C86F18}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ InlineFunctionExpansion="0"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="0"
+ OmitFramePointers="false"
+ AdditionalIncludeDirectories="..\Main;..\Renderer;..\Shader;..\Common;..\SwiftAsm;..\libjpeg;..\SwiftShader;..\D3D9;..\Reactor;..\LLVM\include;..\LLVM\win32"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;D3D9DLL_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
+ MinimalRebuild="true"
+ ExceptionHandling="1"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="1"
+ ForceConformanceInForLoopScope="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ ForcedIncludeFiles="ExceptionHandling.hpp"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="version.lib dxguid.lib comctl32.lib user32.lib gdi32.lib"
+ OutputFile="$(OutDir)/d3d9.dll"
+ LinkIncremental="2"
+ IgnoreDefaultLibraryNames="libci.lib"
+ ModuleDefinitionFile="d3d9.def"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/D3D9.pdb"
+ SubSystem="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(OutDir)/D3D9.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ InlineFunctionExpansion="0"
+ FavorSizeOrSpeed="0"
+ OmitFramePointers="false"
+ AdditionalIncludeDirectories="..\Main;..\Renderer;..\Shader;..\Common;..\SwiftAsm;..\libjpeg;..\SwiftShader;..\D3D9;..\Reactor;..\LLVM\include;..\LLVM\win32"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;D3D9DLL_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
+ MinimalRebuild="true"
+ ExceptionHandling="1"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="1"
+ ForceConformanceInForLoopScope="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ ForcedIncludeFiles="ExceptionHandling.hpp"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="version.lib dxguid.lib comctl32.lib user32.lib gdi32.lib"
+ OutputFile="$(OutDir)/d3d9.dll"
+ LinkIncremental="2"
+ IgnoreDefaultLibraryNames="libci.lib"
+ ModuleDefinitionFile="d3d9.def"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/D3D9.pdb"
+ SubSystem="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(OutDir)/D3D9.lib"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="0"
+ OmitFramePointers="true"
+ WholeProgramOptimization="false"
+ AdditionalIncludeDirectories="..\Main;..\Renderer;..\Shader;..\Common;..\SwiftAsm;..\libjpeg;..\SwiftShader;..\D3D9;..\Reactor;..\LLVM\include;..\LLVM\win32"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;D3D9DLL_EXPORTS;DLL;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;_HAS_EXCEPTIONS=0"
+ ExceptionHandling="1"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ ForceConformanceInForLoopScope="true"
+ UsePrecompiledHeader="0"
+ ExpandAttributedSource="false"
+ BrowseInformation="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="0"
+ ForcedIncludeFiles="ExceptionHandling.hpp"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="version.lib dxguid.lib comctl32.lib user32.lib gdi32.lib"
+ OutputFile="$(OutDir)/d3d9.dll"
+ LinkIncremental="1"
+ IgnoreDefaultLibraryNames="libci.lib"
+ ModuleDefinitionFile="d3d9.def"
+ GenerateDebugInformation="false"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ SetChecksum="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(OutDir)/D3D9.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/MP"
+ Optimization="2"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="0"
+ OmitFramePointers="true"
+ WholeProgramOptimization="false"
+ AdditionalIncludeDirectories="..\Main;..\Renderer;..\Shader;..\Common;..\SwiftAsm;..\libjpeg;..\SwiftShader;..\D3D9;..\Reactor;..\LLVM\include;..\LLVM\win32"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;D3D9DLL_EXPORTS;DLL;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;_HAS_EXCEPTIONS=0"
+ ExceptionHandling="1"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ ForceConformanceInForLoopScope="true"
+ UsePrecompiledHeader="0"
+ ExpandAttributedSource="false"
+ BrowseInformation="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="0"
+ ForcedIncludeFiles="ExceptionHandling.hpp"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="version.lib dxguid.lib comctl32.lib user32.lib gdi32.lib"
+ OutputFile="$(OutDir)/d3d9.dll"
+ LinkIncremental="1"
+ IgnoreDefaultLibraryNames="libci.lib"
+ ModuleDefinitionFile="d3d9.def"
+ GenerateDebugInformation="false"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ SetChecksum="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(OutDir)/D3D9.lib"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\Capabilities.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\D3D9.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AssemblerOutput="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AssemblerOutput="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AssemblerOutput="3"
+ ShowIncludes="false"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AssemblerOutput="3"
+ ShowIncludes="false"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\Debug.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3D9.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3D9Ex.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DBaseTexture9.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DCubeTexture9.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DDevice9.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DDevice9Ex.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DIndexBuffer9.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DPixelShader9.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DQuery9.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DResource9.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DStateBlock9.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DSurface9.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DSwapChain9.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DTexture9.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DVertexBuffer9.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DVertexDeclaration9.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DVertexShader9.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DVolume9.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DVolumeTexture9.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\SwiftShader.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Unknown.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\Capabilities.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Debug.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3D9.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3D9Ex.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DBaseTexture9.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DCubeTexture9.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DDevice9.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DDevice9Ex.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DIndexBuffer9.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DPixelShader9.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DQuery9.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DResource9.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DStateBlock9.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DSurface9.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DSwapChain9.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DTexture9.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DVertexBuffer9.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DVertexDeclaration9.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DVertexShader9.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DVolume9.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Direct3DVolumeTexture9.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ <File
+ RelativePath=".\SwiftShader.h"
+ >
+ </File>
+ <File
+ RelativePath=".\SwiftShader.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Unknown.hpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath=".\D3D9.rc"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\d3d9.def"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/D3D9/D3D9.vcxproj b/src/D3D9/D3D9.vcxproj
new file mode 100644
index 0000000..33de5a2
--- /dev/null
+++ b/src/D3D9/D3D9.vcxproj
@@ -0,0 +1,462 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Profile|Win32">
+ <Configuration>Profile</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Profile|x64">
+ <Configuration>Profile</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{F18D5ABF-CA3A-4B74-BDB2-4A1957C86F18}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\$(Configuration)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">$(Platform)\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\$(Configuration)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">$(Platform)\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">$(Platform)\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">$(Platform)\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">false</LinkIncremental>
+ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(DXSDK_DIR)Lib\x86;$(LibraryPath)</LibraryPath>
+ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(DXSDK_DIR)Lib\x86;$(LibraryPath)</LibraryPath>
+ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">$(DXSDK_DIR)Lib\x86;$(LibraryPath)</LibraryPath>
+ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(DXSDK_DIR)Lib\x64;$(LibraryPath)</LibraryPath>
+ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">$(DXSDK_DIR)Lib\x64;$(LibraryPath)</LibraryPath>
+ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(DXSDK_DIR)Lib\x64;$(LibraryPath)</LibraryPath>
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(DXSDK_DIR)Include;$(IncludePath)</IncludePath>
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">$(DXSDK_DIR)Include;$(IncludePath)</IncludePath>
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(DXSDK_DIR)Include;$(IncludePath)</IncludePath>
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(DXSDK_DIR)Include;$(IncludePath)</IncludePath>
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">$(DXSDK_DIR)Include;$(IncludePath)</IncludePath>
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(DXSDK_DIR)Include;$(IncludePath)</IncludePath>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\;..\Main;..\Renderer;..\Shader;..\Common;..\SwiftAsm;..\libjpeg;..\SwiftShader;..\D3D9;..\Reactor;..\LLVM\include;..\LLVM\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;D3D9DLL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ForcedIncludeFiles>ExceptionHandling.hpp;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>dxguid.lib;WS2_32.lib;comctl32.lib;user32.lib;gdi32.lib;Psapi.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>libci.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>d3d9.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)D3D9.pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)D3D9.lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <OutputFile>$(OutDir)d3d9.dll</OutputFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\;..\Main;..\Renderer;..\Shader;..\Common;..\SwiftAsm;..\libjpeg;..\SwiftShader;..\D3D9;..\Reactor;..\LLVM\include;..\LLVM\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;D3D9DLL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ForcedIncludeFiles>ExceptionHandling.hpp;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>dxguid.lib;WS2_32.lib;comctl32.lib;user32.lib;gdi32.lib;Psapi.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>libci.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>d3d9.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)D3D9.pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)D3D9.lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ <OutputFile>$(OutDir)d3d9.dll</OutputFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>..\;..\Main;..\Renderer;..\Shader;..\Common;..\SwiftAsm;..\libjpeg;..\SwiftShader;..\D3D9;..\Reactor;..\LLVM\include;..\LLVM\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;D3D9DLL_EXPORTS;DLL;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <ExpandAttributedSource>false</ExpandAttributedSource>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <ForcedIncludeFiles>ExceptionHandling.hpp;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
+ <StringPooling>true</StringPooling>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>dxguid.lib;WS2_32.lib;comctl32.lib;user32.lib;gdi32.lib;Psapi.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>libci.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>d3d9.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <SetChecksum>true</SetChecksum>
+ <ImportLibrary>$(OutDir)D3D9.lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <OutputFile>$(OutDir)d3d9.dll</OutputFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>..\;..\Main;..\Renderer;..\Shader;..\Common;..\SwiftAsm;..\libjpeg;..\SwiftShader;..\D3D9;..\Reactor;..\LLVM\include;..\LLVM\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;D3D9DLL_EXPORTS;DLL;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <ExpandAttributedSource>false</ExpandAttributedSource>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ForcedIncludeFiles>ExceptionHandling.hpp;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
+ <StringPooling>true</StringPooling>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>dxguid.lib;WS2_32.lib;comctl32.lib;user32.lib;gdi32.lib;Psapi.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>libci.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>d3d9.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <SetChecksum>true</SetChecksum>
+ <ImportLibrary>$(OutDir)D3D9.lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ <OutputFile>$(OutDir)d3d9.dll</OutputFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>..\;..\Main;..\Renderer;..\Shader;..\Common;..\SwiftAsm;..\libjpeg;..\SwiftShader;..\D3D9;..\Reactor;..\LLVM\include;..\LLVM\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;D3D9DLL_EXPORTS;DLL;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <ExpandAttributedSource>false</ExpandAttributedSource>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <ForcedIncludeFiles>ExceptionHandling.hpp;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
+ <StringPooling>true</StringPooling>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>dxguid.lib;WS2_32.lib;comctl32.lib;user32.lib;gdi32.lib;Psapi.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>libci.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>d3d9.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <SetChecksum>true</SetChecksum>
+ <ImportLibrary>$(OutDir)D3D9.lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <OutputFile>$(OutDir)d3d9.dll</OutputFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>..\;..\Main;..\Renderer;..\Shader;..\Common;..\SwiftAsm;..\libjpeg;..\SwiftShader;..\D3D9;..\Reactor;..\LLVM\include;..\LLVM\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;D3D9DLL_EXPORTS;DLL;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <ExpandAttributedSource>false</ExpandAttributedSource>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ForcedIncludeFiles>ExceptionHandling.hpp;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
+ <StringPooling>true</StringPooling>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>dxguid.lib;WS2_32.lib;comctl32.lib;user32.lib;gdi32.lib;Psapi.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>libci.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>d3d9.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <SetChecksum>true</SetChecksum>
+ <ImportLibrary>$(OutDir)D3D9.lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ <OutputFile>$(OutDir)d3d9.dll</OutputFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="Capabilities.cpp" />
+ <ClCompile Include="D3D9.cpp" />
+ <ClCompile Include="Debug.cpp" />
+ <ClCompile Include="Direct3D9.cpp" />
+ <ClCompile Include="Direct3D9Ex.cpp" />
+ <ClCompile Include="Direct3DBaseTexture9.cpp" />
+ <ClCompile Include="Direct3DCubeTexture9.cpp" />
+ <ClCompile Include="Direct3DDevice9.cpp" />
+ <ClCompile Include="Direct3DDevice9Ex.cpp" />
+ <ClCompile Include="Direct3DIndexBuffer9.cpp" />
+ <ClCompile Include="Direct3DPixelShader9.cpp" />
+ <ClCompile Include="Direct3DQuery9.cpp" />
+ <ClCompile Include="Direct3DResource9.cpp" />
+ <ClCompile Include="Direct3DStateBlock9.cpp" />
+ <ClCompile Include="Direct3DSurface9.cpp" />
+ <ClCompile Include="Direct3DSwapChain9.cpp" />
+ <ClCompile Include="Direct3DTexture9.cpp" />
+ <ClCompile Include="Direct3DVertexBuffer9.cpp" />
+ <ClCompile Include="Direct3DVertexDeclaration9.cpp" />
+ <ClCompile Include="Direct3DVertexShader9.cpp" />
+ <ClCompile Include="Direct3DVolume9.cpp" />
+ <ClCompile Include="Direct3DVolumeTexture9.cpp" />
+ <ClCompile Include="SwiftShader.cpp" />
+ <ClCompile Include="Unknown.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="Capabilities.hpp" />
+ <ClInclude Include="Debug.hpp" />
+ <ClInclude Include="Direct3D9.hpp" />
+ <ClInclude Include="Direct3D9Ex.hpp" />
+ <ClInclude Include="Direct3DBaseTexture9.hpp" />
+ <ClInclude Include="Direct3DCubeTexture9.hpp" />
+ <ClInclude Include="Direct3DDevice9.hpp" />
+ <ClInclude Include="Direct3DDevice9Ex.hpp" />
+ <ClInclude Include="Direct3DIndexBuffer9.hpp" />
+ <ClInclude Include="Direct3DPixelShader9.hpp" />
+ <ClInclude Include="Direct3DQuery9.hpp" />
+ <ClInclude Include="Direct3DResource9.hpp" />
+ <ClInclude Include="Direct3DStateBlock9.hpp" />
+ <ClInclude Include="Direct3DSurface9.hpp" />
+ <ClInclude Include="Direct3DSwapChain9.hpp" />
+ <ClInclude Include="Direct3DTexture9.hpp" />
+ <ClInclude Include="Direct3DVertexBuffer9.hpp" />
+ <ClInclude Include="Direct3DVertexDeclaration9.hpp" />
+ <ClInclude Include="Direct3DVertexShader9.hpp" />
+ <ClInclude Include="Direct3DVolume9.hpp" />
+ <ClInclude Include="Direct3DVolumeTexture9.hpp" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="SwiftShader.h" />
+ <ClInclude Include="SwiftShader.hpp" />
+ <ClInclude Include="Unknown.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="D3D9.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="d3d9.def" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\LLVM\win32\Analysis\Analysis.vcxproj">
+ <Project>{0622e827-8464-489d-8b1c-b0b496f35c08}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\LLVM\win32\CodeGen\CodeGen.vcxproj">
+ <Project>{08ceb1bb-c2a4-4587-b9a9-aedb8fb44897}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\LLVM\win32\ExecutionEngine\ExecutionEngine.vcxproj">
+ <Project>{76295ae8-a083-460e-9f80-6f2b8923264a}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\LLVM\win32\MC\MC.vcxproj">
+ <Project>{12d00cfa-e393-4857-a436-c7324849de51}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\LLVM\win32\Support\Support.vcxproj">
+ <Project>{28aa9146-3482-4f41-9cc6-407b1d258508}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\LLVM\win32\System\System.vcxproj">
+ <Project>{0f8407f3-fa23-4cf1-83a9-dcbe0b361489}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\LLVM\win32\Target\Target.vcxproj">
+ <Project>{059fbab8-c76d-48a0-aa75-3c57bd3eafe4}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\LLVM\win32\Transforms\Transforms.vcxproj">
+ <Project>{c59374c1-9fc0-4147-b836-327dfdc52d99}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\LLVM\win32\VMCore\VMCore.vcxproj">
+ <Project>{45cd78d7-c5d9-47fe-ad12-f3251eedaffb}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\LLVM\win32\x86\x86.vcxproj">
+ <Project>{144eebf6-8c9b-4473-b715-2c821666af6c}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\Reactor\Reactor.vcxproj">
+ <Project>{28fd076d-10b5-4bd8-a4cf-f44c7002a803}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\SwiftShader\SwiftShader.vcxproj">
+ <Project>{7b02cb19-4cdf-4f79-bc9b-7f3f6164a003}</Project>
+ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/src/D3D9/D3D9.vcxproj.filters b/src/D3D9/D3D9.vcxproj.filters
new file mode 100644
index 0000000..efefb3e
--- /dev/null
+++ b/src/D3D9/D3D9.vcxproj.filters
@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="Capabilities.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="D3D9.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Debug.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Direct3D9.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Direct3D9Ex.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Direct3DBaseTexture9.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Direct3DCubeTexture9.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Direct3DDevice9.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Direct3DDevice9Ex.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Direct3DIndexBuffer9.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Direct3DPixelShader9.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Direct3DQuery9.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Direct3DResource9.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Direct3DStateBlock9.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Direct3DSurface9.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Direct3DSwapChain9.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Direct3DTexture9.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Direct3DVertexBuffer9.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Direct3DVertexDeclaration9.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Direct3DVertexShader9.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Direct3DVolume9.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Direct3DVolumeTexture9.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="SwiftShader.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Unknown.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="Capabilities.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Debug.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Direct3D9.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Direct3D9Ex.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Direct3DBaseTexture9.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Direct3DCubeTexture9.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Direct3DDevice9.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Direct3DDevice9Ex.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Direct3DIndexBuffer9.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Direct3DPixelShader9.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Direct3DQuery9.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Direct3DResource9.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Direct3DStateBlock9.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Direct3DSurface9.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Direct3DSwapChain9.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Direct3DTexture9.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Direct3DVertexBuffer9.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Direct3DVertexDeclaration9.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Direct3DVertexShader9.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Direct3DVolume9.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Direct3DVolumeTexture9.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="SwiftShader.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="SwiftShader.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Unknown.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="D3D9.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="d3d9.def" />
+ </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/src/D3D9/Debug.cpp b/src/D3D9/Debug.cpp
new file mode 100644
index 0000000..0ad0731
--- /dev/null
+++ b/src/D3D9/Debug.cpp
@@ -0,0 +1,14 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Debug.hpp"
+
+int Trace::indent = 0;
diff --git a/src/D3D9/Debug.hpp b/src/D3D9/Debug.hpp
new file mode 100644
index 0000000..eb7ed51
--- /dev/null
+++ b/src/D3D9/Debug.hpp
@@ -0,0 +1,170 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef Debug_hpp
+#define Debug_hpp
+
+#ifndef WIN32_LEAN_AND_MEAN
+ #define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#include <d3d9.h>
+#include <stdio.h>
+#include <guiddef.h>
+#include <assert.h>
+
+#define APPEND(x, y) x ## y
+#define MACRO_APPEND(x, y) APPEND(x, y)
+#define UNIQUE_IDENTIFIER(prefix) MACRO_APPEND(prefix, __COUNTER__)
+
+struct Trace
+{
+ Trace(const char *format, ...)
+ {
+ if(false)
+ {
+ FILE *file = fopen("debug.txt", "a");
+
+ if(file)
+ {
+ for(int i = 0; i < indent; i++) fprintf(file, " ");
+
+ va_list vararg;
+ va_start(vararg, format);
+ vfprintf(file, format, vararg);
+ va_end(vararg);
+
+ fclose(file);
+ }
+ }
+
+ indent++;
+ }
+
+ ~Trace()
+ {
+ indent--;
+ }
+
+ static int indent;
+};
+
+#ifndef NDEBUG
+ #define TRACE(format, ...) Trace UNIQUE_IDENTIFIER(_tracer_)("[0x%0.8X]%s("format")\n", this, __FUNCTION__, __VA_ARGS__)
+ #define GTRACE(format, ...) Trace("%s("format")\n", __FUNCTION__, __VA_ARGS__)
+#else
+ #define TRACE(...) ((void)0)
+ #define GTRACE(...) ((void)0)
+#endif
+
+#ifndef NDEBUG
+ #define ASSERT(expression) {if(!(expression)) Trace("\t! Assert failed in %s(%d): "#expression"\n", __FUNCTION__, __LINE__); assert(expression);}
+#else
+ #define ASSERT assert
+#endif
+
+#ifndef NDEBUG
+ #define UNIMPLEMENTED() {Trace("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); ASSERT(false);}
+#else
+ #define UNIMPLEMENTED() ((void)0)
+#endif
+
+#ifndef NDEBUG
+ #define NOINTERFACE(iid) _NOINTERFACE(__FUNCTION__, iid)
+
+ inline long _NOINTERFACE(const char *function, const IID &iid)
+ {
+ Trace("\t! No interface {0x%0.8X, 0x%0.4X, 0x%0.4X, 0x%0.2X, 0x%0.2X, 0x%0.2X, 0x%0.2X, 0x%0.2X, 0x%0.2X, 0x%0.2X, 0x%0.2X} for %s\n", iid.Data1, iid.Data2, iid.Data3, iid.Data4[0], iid.Data4[1], iid.Data4[2], iid.Data4[3], iid.Data4[4], iid.Data4[5], iid.Data4[6], iid.Data4[7], function);
+
+ return E_NOINTERFACE;
+ }
+#else
+ #define NOINTERFACE(iid) E_NOINTERFACE
+#endif
+
+#ifndef NDEBUG
+ inline long INVALIDCALL()
+ {
+ Trace("\t! D3DERR_INVALIDCALL\n");
+
+ return D3DERR_INVALIDCALL;
+ }
+#else
+ #define INVALIDCALL() D3DERR_INVALIDCALL
+#endif
+
+#ifndef NDEBUG
+ inline long OUTOFMEMORY()
+ {
+ Trace("\t! E_OUTOFMEMORY\n");
+
+ return E_OUTOFMEMORY;
+ }
+#else
+ #define OUTOFMEMORY() E_OUTOFMEMORY
+#endif
+
+#ifndef NDEBUG
+ inline long OUTOFVIDEOMEMORY()
+ {
+ Trace("\t! D3DERR_OUTOFVIDEOMEMORY\n");
+
+ return D3DERR_OUTOFVIDEOMEMORY;
+ }
+#else
+ #define OUTOFVIDEOMEMORY() D3DERR_OUTOFVIDEOMEMORY
+#endif
+
+#ifndef NDEBUG
+ inline long NOTAVAILABLE()
+ {
+ Trace("\t! D3DERR_NOTAVAILABLE\n");
+
+ return D3DERR_NOTAVAILABLE;
+ }
+#else
+ #define NOTAVAILABLE() D3DERR_NOTAVAILABLE
+#endif
+
+#ifndef NDEBUG
+ inline long NOTFOUND()
+ {
+ Trace("\t! D3DERR_NOTFOUND\n");
+
+ return D3DERR_NOTFOUND;
+ }
+#else
+ #define NOTFOUND() D3DERR_NOTFOUND
+#endif
+
+#ifndef NDEBUG
+ inline long MOREDATA()
+ {
+ Trace("\t! D3DERR_MOREDATA\n");
+
+ return D3DERR_MOREDATA;
+ }
+#else
+ #define MOREDATA() D3DERR_MOREDATA
+#endif
+
+#ifndef NDEBUG
+ inline long FAIL()
+ {
+ Trace("\t! E_FAIL\n");
+
+ return E_FAIL;
+ }
+#else
+ #define FAIL() E_FAIL
+#endif
+
+#endif // Debug_hpp
diff --git a/src/D3D9/Direct3D9.cpp b/src/D3D9/Direct3D9.cpp
new file mode 100644
index 0000000..298b22f
--- /dev/null
+++ b/src/D3D9/Direct3D9.cpp
@@ -0,0 +1,1637 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3D9.hpp"
+
+#include "Direct3DDevice9.hpp"
+#include "Capabilities.hpp"
+#include "SwiftShader.hpp"
+#include "Configurator.hpp"
+#include "Debug.hpp"
+#include "CPUID.hpp"
+#include "Version.h"
+#include "Config.hpp"
+
+#define COMPILE_MULTIMON_STUBS
+#include <multimon.h>
+#include <assert.h>
+#include <psapi.h>
+
+namespace D3D9
+{
+ Direct3D9::Direct3D9(int version, const HINSTANCE instance) : version(version), instance(instance)
+ {
+ displayMode = 0;
+ numDisplayModes = 0;
+
+ DEVMODE devmode;
+ devmode.dmSize = sizeof(DEVMODE);
+
+ // Count number of display modes
+ while(EnumDisplaySettings(0, numDisplayModes, &devmode)) // FIXME: Only enumarate internal modes!
+ {
+ numDisplayModes++;
+ }
+
+ displayMode = new DEVMODE[numDisplayModes];
+
+ // Store display modes information
+ for(int i = 0; i < numDisplayModes; i++)
+ {
+ displayMode[i].dmSize = sizeof(DEVMODE);
+ EnumDisplaySettings(0, i, &displayMode[i]);
+ }
+
+ d3d9Lib = 0;
+ d3d9 = 0;
+
+ sw::Configurator ini("SwiftShader.ini");
+
+ disableAlphaMode = ini.getBoolean("Testing", "DisableAlphaMode", false);
+ disable10BitMode = ini.getBoolean("Testing", "Disable10BitMode", false);
+
+ int ps = ini.getInteger("Capabilities", "PixelShaderVersion", 30);
+ int vs = ini.getInteger("Capabilities", "VertexShaderVersion", 30);
+
+ if(ps == 0) pixelShaderVersionX = D3DPS_VERSION(0, 0);
+ else if(ps <= 11) pixelShaderVersionX = D3DPS_VERSION(1, 1);
+ else if(ps <= 12) pixelShaderVersionX = D3DPS_VERSION(1, 2);
+ else if(ps <= 13) pixelShaderVersionX = D3DPS_VERSION(1, 3);
+ else if(ps <= 14) pixelShaderVersionX = D3DPS_VERSION(1, 4);
+ else if(ps <= 20) pixelShaderVersionX = D3DPS_VERSION(2, 0);
+ else if(ps <= 21) pixelShaderVersionX = D3DPS_VERSION(2, 1);
+ else pixelShaderVersionX = D3DPS_VERSION(3, 0);
+
+ if(vs == 0) vertexShaderVersionX = D3DVS_VERSION(0, 0);
+ else if(vs <= 11) vertexShaderVersionX = D3DVS_VERSION(1, 1);
+ else if(vs <= 20) vertexShaderVersionX = D3DVS_VERSION(2, 0);
+ else if(vs <= 21) vertexShaderVersionX = D3DVS_VERSION(2, 1);
+ else vertexShaderVersionX = D3DVS_VERSION(3, 0);
+
+ pixelShaderArbitrarySwizzle = 0;
+ pixelShaderGradientInstructions = 0;
+ pixelShaderPredication = 0;
+ pixelShaderNoDependentReadLimit = 0;
+ pixelShaderNoTexInstructionLimit = 0;
+
+ pixelShaderDynamicFlowControlDepth = D3DPS20_MIN_DYNAMICFLOWCONTROLDEPTH;
+ pixelShaderStaticFlowControlDepth = D3DPS20_MIN_STATICFLOWCONTROLDEPTH;
+
+ if(ps >= 21)
+ {
+ pixelShaderArbitrarySwizzle = D3DPS20CAPS_ARBITRARYSWIZZLE;
+ pixelShaderGradientInstructions = D3DPS20CAPS_GRADIENTINSTRUCTIONS;
+ pixelShaderPredication = D3DPS20CAPS_PREDICATION;
+ pixelShaderNoDependentReadLimit = D3DPS20CAPS_NODEPENDENTREADLIMIT;
+ pixelShaderNoTexInstructionLimit = D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
+
+ pixelShaderDynamicFlowControlDepth = D3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH;
+ pixelShaderStaticFlowControlDepth = D3DPS20_MAX_STATICFLOWCONTROLDEPTH;
+ }
+
+ vertexShaderPredication = 0;
+ vertexShaderDynamicFlowControlDepth = 0;
+
+ if(vs >= 21)
+ {
+ vertexShaderPredication = D3DVS20CAPS_PREDICATION;
+ vertexShaderDynamicFlowControlDepth = D3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH;
+ }
+
+ textureMemory = 1024 * 1024 * ini.getInteger("Capabilities", "TextureMemory", 256);
+
+ int shadowMapping = ini.getInteger("Testing", "ShadowMapping", 3);
+
+ if(shadowMapping != 2 && shadowMapping != 3) // No DST support
+ {
+ Capabilities::Texture::DepthStencil::D32 = false;
+ Capabilities::Texture::DepthStencil::D24S8 = false;
+ Capabilities::Texture::DepthStencil::D24X8 = false;
+ Capabilities::Texture::DepthStencil::D16 = false;
+ Capabilities::Texture::DepthStencil::D24FS8 = false;
+ Capabilities::Texture::DepthStencil::D32F_LOCKABLE = false;
+
+ Capabilities::Texture::D32 = false;
+ Capabilities::Texture::D24S8 = false;
+ Capabilities::Texture::D24X8 = false;
+ Capabilities::Texture::D16 = false;
+ Capabilities::Texture::D24FS8 = false;
+ Capabilities::Texture::D32F_LOCKABLE = false;
+ }
+
+ if(shadowMapping != 1 && shadowMapping != 3) // No Fetch4 support
+ {
+ Capabilities::Texture::DepthStencil::DF24 = false;
+ Capabilities::Texture::DepthStencil::DF16 = false;
+
+ Capabilities::Texture::DF24 = false;
+ Capabilities::Texture::DF16 = false;
+ }
+ }
+
+ Direct3D9::~Direct3D9()
+ {
+ delete[] displayMode;
+ displayMode = 0;
+
+ if(d3d9)
+ {
+ d3d9->Release();
+ d3d9 = 0;
+ }
+
+ if(d3d9Lib)
+ {
+ FreeLibrary(d3d9Lib);
+ d3d9Lib = 0;
+ }
+ }
+
+ long Direct3D9::QueryInterface(const IID &iid, void **object)
+ {
+ TRACE("const IID &iid = 0x%0.8p, void **object = 0x%0.8p", iid, object);
+
+ if(iid == IID_IDirect3D9 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+ else if(iid == IID_SwiftShaderPrivateV1)
+ {
+ SwiftShader *swiftShader = new SwiftShader(this);
+
+ *object = swiftShader;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long Direct3D9::AddRef()
+ {
+ TRACE("void");
+
+ return Unknown::AddRef();
+ }
+
+ unsigned long Direct3D9::Release()
+ {
+ TRACE("void");
+
+ return Unknown::Release();
+ }
+
+ long Direct3D9::CheckDepthStencilMatch(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT adapterFormat, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat)
+ {
+ TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DFORMAT adapterFormat = %d, D3DFORMAT renderTargetFormat = %d, D3DFORMAT depthStencilFormat = %d", adapter, deviceType, adapterFormat, renderTargetFormat, depthStencilFormat);
+
+ if(deviceType != D3DDEVTYPE_HAL)
+ {
+ loadSystemD3D9();
+
+ if(d3d9)
+ {
+ return d3d9->CheckDepthStencilMatch(adapter, deviceType, adapterFormat, renderTargetFormat, depthStencilFormat);
+ }
+ else
+ {
+ return CheckDepthStencilMatch(adapter, D3DDEVTYPE_HAL, adapterFormat, renderTargetFormat, depthStencilFormat);
+ }
+ }
+
+ return D3D_OK; // Any format combination is ok
+ }
+
+ long Direct3D9::CheckDeviceFormat(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT adapterFormat, unsigned long usage, D3DRESOURCETYPE resourceType, D3DFORMAT checkFormat)
+ {
+ TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DFORMAT adapterFormat = %d, unsigned long usage = %d, D3DRESOURCETYPE resourceType = %d, D3DFORMAT checkFormat = %d", adapter, deviceType, adapterFormat, usage, resourceType, checkFormat);
+
+ if(deviceType != D3DDEVTYPE_HAL)
+ {
+ loadSystemD3D9();
+
+ if(d3d9)
+ {
+ return d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, usage, resourceType, checkFormat);
+ }
+ else
+ {
+ return CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, adapterFormat, usage, resourceType, checkFormat);
+ }
+ }
+
+ if(usage & D3DUSAGE_QUERY_SRGBREAD)
+ {
+ if(!Capabilities::isSRGBreadable(checkFormat))
+ {
+ return NOTAVAILABLE();
+ }
+ }
+
+ if(usage & D3DUSAGE_QUERY_SRGBWRITE)
+ {
+ if(!Capabilities::isSRGBwritable(checkFormat))
+ {
+ return NOTAVAILABLE();
+ }
+ }
+
+ // ATI hack to indicate instancing support on SM 2.0 hardware
+ if(checkFormat == D3DFMT_INST && pixelShaderVersionX >= D3DPS_VERSION(2, 0) && pixelShaderVersionX < D3DPS_VERSION(3, 0))
+ {
+ return D3D_OK;
+ }
+
+ switch(resourceType)
+ {
+ case D3DRTYPE_SURFACE:
+ if(usage & D3DUSAGE_RENDERTARGET)
+ {
+ switch(checkFormat)
+ {
+ case D3DFMT_NULL: if(!Capabilities::Surface::RenderTarget::NULL_) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R8G8B8: if(!Capabilities::Surface::RenderTarget::R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R5G6B5: if(!Capabilities::Surface::RenderTarget::R5G6B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X1R5G5B5: if(!Capabilities::Surface::RenderTarget::X1R5G5B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A1R5G5B5: if(!Capabilities::Surface::RenderTarget::A1R5G5B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A4R4G4B4: if(!Capabilities::Surface::RenderTarget::A4R4G4B4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R3G3B2: if(!Capabilities::Surface::RenderTarget::R3G3B2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8R3G3B2: if(!Capabilities::Surface::RenderTarget::A8R3G3B2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X4R4G4B4: if(!Capabilities::Surface::RenderTarget::X4R4G4B4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8R8G8B8: if(!Capabilities::Surface::RenderTarget::A8R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8R8G8B8: if(!Capabilities::Surface::RenderTarget::X8R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8B8G8R8: if(!Capabilities::Surface::RenderTarget::A8B8G8R8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8B8G8R8: if(!Capabilities::Surface::RenderTarget::X8B8G8R8) return NOTAVAILABLE(); else return D3D_OK;
+ // Integer HDR formats
+ case D3DFMT_G16R16: if(!Capabilities::Surface::RenderTarget::G16R16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2B10G10R10: if(!Capabilities::Surface::RenderTarget::A2B10G10R10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2R10G10B10: if(!Capabilities::Surface::RenderTarget::A2R10G10B10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A16B16G16R16: if(!Capabilities::Surface::RenderTarget::A16B16G16R16) return NOTAVAILABLE(); else return D3D_OK;
+ // Floating-point formats
+ case D3DFMT_R16F: if(!Capabilities::Surface::RenderTarget::R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_G16R16F: if(!Capabilities::Surface::RenderTarget::G16R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A16B16G16R16F: if(!Capabilities::Surface::RenderTarget::A16B16G16R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R32F: if(!Capabilities::Surface::RenderTarget::R32F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_G32R32F: if(!Capabilities::Surface::RenderTarget::G32R32F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A32B32G32R32F: if(!Capabilities::Surface::RenderTarget::A32B32G32R32F) return NOTAVAILABLE(); else return D3D_OK;
+ default:
+ return NOTAVAILABLE();
+ }
+ }
+ else if(usage & D3DUSAGE_DEPTHSTENCIL)
+ {
+ switch(checkFormat)
+ {
+ case D3DFMT_D32: if(!Capabilities::Surface::DepthStencil::D32) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D24S8: if(!Capabilities::Surface::DepthStencil::D24S8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D24X8: if(!Capabilities::Surface::DepthStencil::D24X8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D16: if(!Capabilities::Surface::DepthStencil::D16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D24FS8: if(!Capabilities::Surface::DepthStencil::D24FS8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D32F_LOCKABLE: if(!Capabilities::Surface::DepthStencil::D32F_LOCKABLE) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DF24: if(!Capabilities::Surface::DepthStencil::DF24) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DF16: if(!Capabilities::Surface::DepthStencil::DF16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_INTZ: if(!Capabilities::Surface::DepthStencil::INTZ) return NOTAVAILABLE(); else return D3D_OK;
+ default:
+ return NOTAVAILABLE();
+ }
+ }
+ else
+ {
+ switch(checkFormat)
+ {
+ case D3DFMT_A8: if(!Capabilities::Surface::A8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R5G6B5: if(!Capabilities::Surface::R5G6B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X1R5G5B5: if(!Capabilities::Surface::X1R5G5B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A1R5G5B5: if(!Capabilities::Surface::A1R5G5B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A4R4G4B4: if(!Capabilities::Surface::A4R4G4B4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R3G3B2: if(!Capabilities::Surface::R3G3B2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8R3G3B2: if(!Capabilities::Surface::A8R3G3B2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X4R4G4B4: if(!Capabilities::Surface::X4R4G4B4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R8G8B8: if(!Capabilities::Surface::R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8R8G8B8: if(!Capabilities::Surface::X8R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8R8G8B8: if(!Capabilities::Surface::A8R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8B8G8R8: if(!Capabilities::Surface::X8B8G8R8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8B8G8R8: if(!Capabilities::Surface::A8B8G8R8) return NOTAVAILABLE(); else return D3D_OK;
+ // Paletted formats
+ case D3DFMT_P8: if(!Capabilities::Surface::P8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8P8: if(!Capabilities::Surface::A8P8) return NOTAVAILABLE(); else return D3D_OK;
+ // Integer HDR formats
+ case D3DFMT_G16R16: if(!Capabilities::Surface::G16R16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2R10G10B10: if(!Capabilities::Surface::A2R10G10B10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2B10G10R10: if(!Capabilities::Surface::A2B10G10R10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A16B16G16R16: if(!Capabilities::Surface::A16B16G16R16) return NOTAVAILABLE(); else return D3D_OK;
+ // Compressed formats
+ case D3DFMT_DXT1: if(!Capabilities::Surface::DXT1) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT2: if(!Capabilities::Surface::DXT2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT3: if(!Capabilities::Surface::DXT3) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT4: if(!Capabilities::Surface::DXT4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT5: if(!Capabilities::Surface::DXT5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_ATI1: if(!Capabilities::Surface::ATI1) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_ATI2: if(!Capabilities::Surface::ATI2) return NOTAVAILABLE(); else return D3D_OK;
+ // Floating-point formats
+ case D3DFMT_R16F: if(!Capabilities::Surface::R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_G16R16F: if(!Capabilities::Surface::G16R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A16B16G16R16F: if(!Capabilities::Surface::A16B16G16R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R32F: if(!Capabilities::Surface::R32F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_G32R32F: if(!Capabilities::Surface::G32R32F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A32B32G32R32F: if(!Capabilities::Surface::A32B32G32R32F) return NOTAVAILABLE(); else return D3D_OK;
+ // Bump map formats
+ case D3DFMT_V8U8: if(!Capabilities::Surface::V8U8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_L6V5U5: if(!Capabilities::Surface::L6V5U5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8L8V8U8: if(!Capabilities::Surface::X8L8V8U8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_Q8W8V8U8: if(!Capabilities::Surface::Q8W8V8U8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_V16U16: if(!Capabilities::Surface::V16U16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2W10V10U10: if(!Capabilities::Surface::A2W10V10U10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_Q16W16V16U16: if(!Capabilities::Surface::Q16W16V16U16) return NOTAVAILABLE(); else return D3D_OK;
+ // Luminance formats
+ case D3DFMT_L8: if(!Capabilities::Surface::L8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A4L4: if(!Capabilities::Surface::A4L4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_L16: if(!Capabilities::Surface::L16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8L8: if(!Capabilities::Surface::A8L8) return NOTAVAILABLE(); else return D3D_OK;
+ // Depth Bounds Test
+ case D3DFMT_NVDB: if(!Capabilities::Surface::NVDB) return NOTAVAILABLE(); else return D3D_OK;
+ // Transparency anti-aliasing
+ case D3DFMT_ATOC: if(!Capabilities::Surface::ATOC) return NOTAVAILABLE(); else return D3D_OK;
+ default:
+ return NOTAVAILABLE();
+ }
+ }
+ case D3DRTYPE_VOLUME:
+ switch(checkFormat)
+ {
+ case D3DFMT_A8: if(!Capabilities::Volume::A8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R5G6B5: if(!Capabilities::Volume::R5G6B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X1R5G5B5: if(!Capabilities::Volume::X1R5G5B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A1R5G5B5: if(!Capabilities::Volume::A1R5G5B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A4R4G4B4: if(!Capabilities::Volume::A4R4G4B4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R3G3B2: if(!Capabilities::Volume::R3G3B2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8R3G3B2: if(!Capabilities::Volume::A8R3G3B2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X4R4G4B4: if(!Capabilities::Volume::X4R4G4B4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R8G8B8: if(!Capabilities::Volume::R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8R8G8B8: if(!Capabilities::Volume::X8R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8R8G8B8: if(!Capabilities::Volume::A8R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8B8G8R8: if(!Capabilities::Volume::X8B8G8R8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8B8G8R8: if(!Capabilities::Volume::A8B8G8R8) return NOTAVAILABLE(); else return D3D_OK;
+ // Paletted formats
+ case D3DFMT_P8: if(!Capabilities::Volume::P8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8P8: if(!Capabilities::Volume::A8P8) return NOTAVAILABLE(); else return D3D_OK;
+ // Integer HDR formats
+ case D3DFMT_G16R16: if(!Capabilities::Volume::G16R16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2R10G10B10: if(!Capabilities::Volume::A2R10G10B10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2B10G10R10: if(!Capabilities::Volume::A2B10G10R10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A16B16G16R16: if(!Capabilities::Volume::A16B16G16R16) return NOTAVAILABLE(); else return D3D_OK;
+ // Compressed formats
+ case D3DFMT_DXT1: if(!Capabilities::Volume::DXT1) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT2: if(!Capabilities::Volume::DXT2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT3: if(!Capabilities::Volume::DXT3) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT4: if(!Capabilities::Volume::DXT4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT5: if(!Capabilities::Volume::DXT5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_ATI1: if(!Capabilities::Volume::ATI1) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_ATI2: if(!Capabilities::Volume::ATI2) return NOTAVAILABLE(); else return D3D_OK;
+ // Floating-point formats
+ case D3DFMT_R16F: if(!Capabilities::Volume::R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_G16R16F: if(!Capabilities::Volume::G16R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A16B16G16R16F: if(!Capabilities::Volume::A16B16G16R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R32F: if(!Capabilities::Volume::R32F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_G32R32F: if(!Capabilities::Volume::G32R32F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A32B32G32R32F: if(!Capabilities::Volume::A32B32G32R32F) return NOTAVAILABLE(); else return D3D_OK;
+ // Bump map formats
+ case D3DFMT_V8U8: if(!Capabilities::Volume::V8U8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_L6V5U5: if(!Capabilities::Volume::L6V5U5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8L8V8U8: if(!Capabilities::Volume::X8L8V8U8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_Q8W8V8U8: if(!Capabilities::Volume::Q8W8V8U8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_V16U16: if(!Capabilities::Volume::V16U16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2W10V10U10: if(!Capabilities::Volume::A2W10V10U10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_Q16W16V16U16: if(!Capabilities::Volume::Q16W16V16U16) return NOTAVAILABLE(); else return D3D_OK;
+ // Luminance formats
+ case D3DFMT_L8: if(!Capabilities::Volume::L8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A4L4: if(!Capabilities::Volume::A4L4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_L16: if(!Capabilities::Volume::L16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8L8: if(!Capabilities::Volume::A8L8) return NOTAVAILABLE(); else return D3D_OK;
+ default:
+ return NOTAVAILABLE();
+ }
+ case D3DRTYPE_CUBETEXTURE:
+ if(usage & D3DUSAGE_RENDERTARGET)
+ {
+ switch(checkFormat)
+ {
+ case D3DFMT_NULL: if(!Capabilities::CubeMap::RenderTarget::NULL_) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R8G8B8: if(!Capabilities::CubeMap::RenderTarget::R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R5G6B5: if(!Capabilities::CubeMap::RenderTarget::R5G6B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X1R5G5B5: if(!Capabilities::CubeMap::RenderTarget::X1R5G5B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A1R5G5B5: if(!Capabilities::CubeMap::RenderTarget::A1R5G5B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A4R4G4B4: if(!Capabilities::CubeMap::RenderTarget::A4R4G4B4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R3G3B2: if(!Capabilities::CubeMap::RenderTarget::R3G3B2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8R3G3B2: if(!Capabilities::CubeMap::RenderTarget::A8R3G3B2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X4R4G4B4: if(!Capabilities::CubeMap::RenderTarget::X4R4G4B4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8R8G8B8: if(!Capabilities::CubeMap::RenderTarget::A8R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8R8G8B8: if(!Capabilities::CubeMap::RenderTarget::X8R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8B8G8R8: if(!Capabilities::CubeMap::RenderTarget::A8B8G8R8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8B8G8R8: if(!Capabilities::CubeMap::RenderTarget::X8B8G8R8) return NOTAVAILABLE(); else return D3D_OK;
+ // Integer HDR formats
+ case D3DFMT_G16R16: if(!Capabilities::CubeMap::RenderTarget::G16R16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2B10G10R10: if(!Capabilities::CubeMap::RenderTarget::A2B10G10R10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2R10G10B10: if(!Capabilities::CubeMap::RenderTarget::A2R10G10B10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A16B16G16R16: if(!Capabilities::CubeMap::RenderTarget::A16B16G16R16) return NOTAVAILABLE(); else return D3D_OK;
+ // Floating-point formats
+ case D3DFMT_R16F: if(!Capabilities::CubeMap::RenderTarget::R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_G16R16F: if(!Capabilities::CubeMap::RenderTarget::G16R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A16B16G16R16F: if(!Capabilities::CubeMap::RenderTarget::A16B16G16R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R32F: if(!Capabilities::CubeMap::RenderTarget::R32F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_G32R32F: if(!Capabilities::CubeMap::RenderTarget::G32R32F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A32B32G32R32F: if(!Capabilities::CubeMap::RenderTarget::A32B32G32R32F) return NOTAVAILABLE(); else return D3D_OK;
+ default:
+ return NOTAVAILABLE();
+ }
+ }
+ else if(usage & D3DUSAGE_DEPTHSTENCIL)
+ {
+ switch(checkFormat)
+ {
+ case D3DFMT_D32: if(!Capabilities::CubeMap::DepthStencil::D32) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D24S8: if(!Capabilities::CubeMap::DepthStencil::D24S8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D24X8: if(!Capabilities::CubeMap::DepthStencil::D24X8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D16: if(!Capabilities::CubeMap::DepthStencil::D16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D24FS8: if(!Capabilities::CubeMap::DepthStencil::D24FS8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D32F_LOCKABLE: if(!Capabilities::CubeMap::DepthStencil::D32F_LOCKABLE) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DF24: if(!Capabilities::CubeMap::DepthStencil::DF24) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DF16: if(!Capabilities::CubeMap::DepthStencil::DF16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_INTZ: if(!Capabilities::CubeMap::DepthStencil::INTZ) return NOTAVAILABLE(); else return D3D_OK;
+ default:
+ return NOTAVAILABLE();
+ }
+ }
+ else
+ {
+ switch(checkFormat)
+ {
+ case D3DFMT_A8: if(!Capabilities::CubeMap::A8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R5G6B5: if(!Capabilities::CubeMap::R5G6B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X1R5G5B5: if(!Capabilities::CubeMap::X1R5G5B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A1R5G5B5: if(!Capabilities::CubeMap::A1R5G5B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A4R4G4B4: if(!Capabilities::CubeMap::A4R4G4B4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R3G3B2: if(!Capabilities::CubeMap::R3G3B2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8R3G3B2: if(!Capabilities::CubeMap::A8R3G3B2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X4R4G4B4: if(!Capabilities::CubeMap::X4R4G4B4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R8G8B8: if(!Capabilities::CubeMap::R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8R8G8B8: if(!Capabilities::CubeMap::X8R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8R8G8B8: if(!Capabilities::CubeMap::A8R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8B8G8R8: if(!Capabilities::CubeMap::X8B8G8R8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8B8G8R8: if(!Capabilities::CubeMap::A8B8G8R8) return NOTAVAILABLE(); else return D3D_OK;
+ // Paletted formats
+ case D3DFMT_P8: if(!Capabilities::CubeMap::P8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8P8: if(!Capabilities::CubeMap::A8P8) return NOTAVAILABLE(); else return D3D_OK;
+ // Integer HDR formats
+ case D3DFMT_G16R16: if(!Capabilities::CubeMap::G16R16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2R10G10B10: if(!Capabilities::CubeMap::A2R10G10B10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2B10G10R10: if(!Capabilities::CubeMap::A2B10G10R10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A16B16G16R16: if(!Capabilities::CubeMap::A16B16G16R16) return NOTAVAILABLE(); else return D3D_OK;
+ // Compressed formats
+ case D3DFMT_DXT1: if(!Capabilities::CubeMap::DXT1) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT2: if(!Capabilities::CubeMap::DXT2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT3: if(!Capabilities::CubeMap::DXT3) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT4: if(!Capabilities::CubeMap::DXT4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT5: if(!Capabilities::CubeMap::DXT5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_ATI1: if(!Capabilities::CubeMap::ATI1) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_ATI2: if(!Capabilities::CubeMap::ATI2) return NOTAVAILABLE(); else return D3D_OK;
+ // Floating-point formats
+ case D3DFMT_R16F: if(!Capabilities::CubeMap::R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_G16R16F: if(!Capabilities::CubeMap::G16R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A16B16G16R16F: if(!Capabilities::CubeMap::A16B16G16R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R32F: if(!Capabilities::CubeMap::R32F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_G32R32F: if(!Capabilities::CubeMap::G32R32F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A32B32G32R32F: if(!Capabilities::CubeMap::A32B32G32R32F) return NOTAVAILABLE(); else return D3D_OK;
+ // Bump map formats
+ case D3DFMT_V8U8: if(!Capabilities::CubeMap::V8U8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_L6V5U5: if(!Capabilities::CubeMap::L6V5U5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8L8V8U8: if(!Capabilities::CubeMap::X8L8V8U8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_Q8W8V8U8: if(!Capabilities::CubeMap::Q8W8V8U8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_V16U16: if(!Capabilities::CubeMap::V16U16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2W10V10U10: if(!Capabilities::CubeMap::A2W10V10U10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_Q16W16V16U16: if(!Capabilities::CubeMap::Q16W16V16U16) return NOTAVAILABLE(); else return D3D_OK;
+ // Luminance formats
+ case D3DFMT_L8: if(!Capabilities::CubeMap::L8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A4L4: if(!Capabilities::CubeMap::A4L4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_L16: if(!Capabilities::CubeMap::L16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8L8: if(!Capabilities::CubeMap::A8L8) return NOTAVAILABLE(); else return D3D_OK;
+ default:
+ return NOTAVAILABLE();
+ }
+ }
+ case D3DRTYPE_VOLUMETEXTURE:
+ switch(checkFormat)
+ {
+ case D3DFMT_A8: if(!Capabilities::VolumeTexture::A8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R5G6B5: if(!Capabilities::VolumeTexture::R5G6B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X1R5G5B5: if(!Capabilities::VolumeTexture::X1R5G5B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A1R5G5B5: if(!Capabilities::VolumeTexture::A1R5G5B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A4R4G4B4: if(!Capabilities::VolumeTexture::A4R4G4B4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R3G3B2: if(!Capabilities::VolumeTexture::R3G3B2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8R3G3B2: if(!Capabilities::VolumeTexture::A8R3G3B2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X4R4G4B4: if(!Capabilities::VolumeTexture::X4R4G4B4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R8G8B8: if(!Capabilities::VolumeTexture::R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8R8G8B8: if(!Capabilities::VolumeTexture::X8R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8R8G8B8: if(!Capabilities::VolumeTexture::A8R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8B8G8R8: if(!Capabilities::VolumeTexture::X8B8G8R8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8B8G8R8: if(!Capabilities::VolumeTexture::A8B8G8R8) return NOTAVAILABLE(); else return D3D_OK;
+ // Paletted formats
+ case D3DFMT_P8: if(!Capabilities::VolumeTexture::P8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8P8: if(!Capabilities::VolumeTexture::A8P8) return NOTAVAILABLE(); else return D3D_OK;
+ // Integer HDR formats
+ case D3DFMT_G16R16: if(!Capabilities::VolumeTexture::G16R16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2R10G10B10: if(!Capabilities::VolumeTexture::A2R10G10B10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2B10G10R10: if(!Capabilities::VolumeTexture::A2B10G10R10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A16B16G16R16: if(!Capabilities::VolumeTexture::A16B16G16R16) return NOTAVAILABLE(); else return D3D_OK;
+ // Compressed formats
+ case D3DFMT_DXT1: if(!Capabilities::VolumeTexture::DXT1) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT2: if(!Capabilities::VolumeTexture::DXT2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT3: if(!Capabilities::VolumeTexture::DXT3) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT4: if(!Capabilities::VolumeTexture::DXT4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT5: if(!Capabilities::VolumeTexture::DXT5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_ATI1: if(!Capabilities::VolumeTexture::ATI1) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_ATI2: if(!Capabilities::VolumeTexture::ATI2) return NOTAVAILABLE(); else return D3D_OK;
+ // Floating-point formats
+ case D3DFMT_R16F: if(!Capabilities::VolumeTexture::R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_G16R16F: if(!Capabilities::VolumeTexture::G16R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A16B16G16R16F: if(!Capabilities::VolumeTexture::A16B16G16R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R32F: if(!Capabilities::VolumeTexture::R32F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_G32R32F: if(!Capabilities::VolumeTexture::G32R32F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A32B32G32R32F: if(!Capabilities::VolumeTexture::A32B32G32R32F) return NOTAVAILABLE(); else return D3D_OK;
+ // Bump map formats
+ case D3DFMT_V8U8: if(!Capabilities::VolumeTexture::V8U8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_L6V5U5: if(!Capabilities::VolumeTexture::L6V5U5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8L8V8U8: if(!Capabilities::VolumeTexture::X8L8V8U8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_Q8W8V8U8: if(!Capabilities::VolumeTexture::Q8W8V8U8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_V16U16: if(!Capabilities::VolumeTexture::V16U16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2W10V10U10: if(!Capabilities::VolumeTexture::A2W10V10U10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_Q16W16V16U16: if(!Capabilities::VolumeTexture::Q16W16V16U16) return NOTAVAILABLE(); else return D3D_OK;
+ // Luminance formats
+ case D3DFMT_L8: if(!Capabilities::VolumeTexture::L8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A4L4: if(!Capabilities::VolumeTexture::A4L4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_L16: if(!Capabilities::VolumeTexture::L16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8L8: if(!Capabilities::VolumeTexture::A8L8) return NOTAVAILABLE(); else return D3D_OK;
+ default:
+ return NOTAVAILABLE();
+ }
+ case D3DRTYPE_TEXTURE:
+ if(usage & D3DUSAGE_RENDERTARGET)
+ {
+ switch(checkFormat)
+ {
+ case D3DFMT_NULL: if(!Capabilities::Texture::RenderTarget::NULL_) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R8G8B8: if(!Capabilities::Texture::RenderTarget::R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R5G6B5: if(!Capabilities::Texture::RenderTarget::R5G6B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X1R5G5B5: if(!Capabilities::Texture::RenderTarget::X1R5G5B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A1R5G5B5: if(!Capabilities::Texture::RenderTarget::A1R5G5B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A4R4G4B4: if(!Capabilities::Texture::RenderTarget::A4R4G4B4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R3G3B2: if(!Capabilities::Texture::RenderTarget::R3G3B2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8R3G3B2: if(!Capabilities::Texture::RenderTarget::A8R3G3B2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X4R4G4B4: if(!Capabilities::Texture::RenderTarget::X4R4G4B4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8R8G8B8: if(!Capabilities::Texture::RenderTarget::A8R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8R8G8B8: if(!Capabilities::Texture::RenderTarget::X8R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8B8G8R8: if(!Capabilities::Texture::RenderTarget::A8B8G8R8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8B8G8R8: if(!Capabilities::Texture::RenderTarget::X8B8G8R8) return NOTAVAILABLE(); else return D3D_OK;
+ // Integer HDR formats
+ case D3DFMT_G16R16: if(!Capabilities::Texture::RenderTarget::G16R16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2B10G10R10: if(!Capabilities::Texture::RenderTarget::A2B10G10R10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2R10G10B10: if(!Capabilities::Texture::RenderTarget::A2R10G10B10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A16B16G16R16: if(!Capabilities::Texture::RenderTarget::A16B16G16R16) return NOTAVAILABLE(); else return D3D_OK;
+ // Floating-point formats
+ case D3DFMT_R16F: if(!Capabilities::Texture::RenderTarget::R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_G16R16F: if(!Capabilities::Texture::RenderTarget::G16R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A16B16G16R16F: if(!Capabilities::Texture::RenderTarget::A16B16G16R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R32F: if(!Capabilities::Texture::RenderTarget::R32F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_G32R32F: if(!Capabilities::Texture::RenderTarget::G32R32F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A32B32G32R32F: if(!Capabilities::Texture::RenderTarget::A32B32G32R32F) return NOTAVAILABLE(); else return D3D_OK;
+ default:
+ return NOTAVAILABLE();
+ }
+ }
+ else if(usage & D3DUSAGE_DEPTHSTENCIL)
+ {
+ switch(checkFormat)
+ {
+ case D3DFMT_D32: if(!Capabilities::Texture::DepthStencil::D32) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D24S8: if(!Capabilities::Texture::DepthStencil::D24S8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D24X8: if(!Capabilities::Texture::DepthStencil::D24X8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D16: if(!Capabilities::Texture::DepthStencil::D16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D24FS8: if(!Capabilities::Texture::DepthStencil::D24FS8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D32F_LOCKABLE: if(!Capabilities::Texture::DepthStencil::D32F_LOCKABLE) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DF24: if(!Capabilities::Texture::DepthStencil::DF24) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DF16: if(!Capabilities::Texture::DepthStencil::DF16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_INTZ: if(!Capabilities::Texture::DepthStencil::INTZ) return NOTAVAILABLE(); else return D3D_OK;
+ default:
+ return NOTAVAILABLE();
+ }
+ }
+ else
+ {
+ switch(checkFormat)
+ {
+ case D3DFMT_NULL: if(!Capabilities::Texture::NULL_) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8: if(!Capabilities::Texture::A8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R5G6B5: if(!Capabilities::Texture::R5G6B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X1R5G5B5: if(!Capabilities::Texture::X1R5G5B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A1R5G5B5: if(!Capabilities::Texture::A1R5G5B5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A4R4G4B4: if(!Capabilities::Texture::A4R4G4B4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R3G3B2: if(!Capabilities::Texture::R3G3B2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8R3G3B2: if(!Capabilities::Texture::A8R3G3B2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X4R4G4B4: if(!Capabilities::Texture::X4R4G4B4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R8G8B8: if(!Capabilities::Texture::R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8R8G8B8: if(!Capabilities::Texture::X8R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8R8G8B8: if(!Capabilities::Texture::A8R8G8B8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8B8G8R8: if(!Capabilities::Texture::X8B8G8R8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8B8G8R8: if(!Capabilities::Texture::A8B8G8R8) return NOTAVAILABLE(); else return D3D_OK;
+ // Paletted formats
+ case D3DFMT_P8: if(!Capabilities::Texture::P8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8P8: if(!Capabilities::Texture::A8P8) return NOTAVAILABLE(); else return D3D_OK;
+ // Integer HDR formats
+ case D3DFMT_G16R16: if(!Capabilities::Texture::G16R16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2R10G10B10: if(!Capabilities::Texture::A2R10G10B10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2B10G10R10: if(!Capabilities::Texture::A2B10G10R10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A16B16G16R16: if(!Capabilities::Texture::A16B16G16R16) return NOTAVAILABLE(); else return D3D_OK;
+ // Compressed formats
+ case D3DFMT_DXT1: if(!Capabilities::Texture::DXT1) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT2: if(!Capabilities::Texture::DXT2) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT3: if(!Capabilities::Texture::DXT3) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT4: if(!Capabilities::Texture::DXT4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DXT5: if(!Capabilities::Texture::DXT5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_ATI1: if(!Capabilities::Texture::ATI1) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_ATI2: if(!Capabilities::Texture::ATI2) return NOTAVAILABLE(); else return D3D_OK;
+ // Floating-point formats
+ case D3DFMT_R16F: if(!Capabilities::Texture::R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_G16R16F: if(!Capabilities::Texture::G16R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A16B16G16R16F: if(!Capabilities::Texture::A16B16G16R16F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_R32F: if(!Capabilities::Texture::R32F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_G32R32F: if(!Capabilities::Texture::G32R32F) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A32B32G32R32F: if(!Capabilities::Texture::A32B32G32R32F) return NOTAVAILABLE(); else return D3D_OK;
+ // Bump map formats
+ case D3DFMT_V8U8: if(!Capabilities::Texture::V8U8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_L6V5U5: if(!Capabilities::Texture::L6V5U5) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_X8L8V8U8: if(!Capabilities::Texture::X8L8V8U8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_Q8W8V8U8: if(!Capabilities::Texture::Q8W8V8U8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_V16U16: if(!Capabilities::Texture::V16U16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A2W10V10U10: if(!Capabilities::Texture::A2W10V10U10) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_Q16W16V16U16: if(!Capabilities::Texture::Q16W16V16U16) return NOTAVAILABLE(); else return D3D_OK;
+ // Luminance formats
+ case D3DFMT_L8: if(!Capabilities::Texture::L8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A4L4: if(!Capabilities::Texture::A4L4) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_L16: if(!Capabilities::Texture::L16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_A8L8: if(!Capabilities::Texture::A8L8) return NOTAVAILABLE(); else return D3D_OK;
+ // Depth formats
+ case D3DFMT_D32: if(!Capabilities::Texture::D32) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D24S8: if(!Capabilities::Texture::D24S8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D24X8: if(!Capabilities::Texture::D24X8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D16: if(!Capabilities::Texture::D16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D24FS8: if(!Capabilities::Texture::D24FS8) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_D32F_LOCKABLE: if(!Capabilities::Texture::D32F_LOCKABLE) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DF24: if(!Capabilities::Texture::DF24) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_DF16: if(!Capabilities::Texture::DF16) return NOTAVAILABLE(); else return D3D_OK;
+ case D3DFMT_INTZ: if(!Capabilities::Texture::INTZ) return NOTAVAILABLE(); else return D3D_OK;
+ default:
+ return NOTAVAILABLE();
+ }
+ }
+ case D3DRTYPE_VERTEXBUFFER:
+ if(checkFormat == D3DFMT_VERTEXDATA)
+ {
+ return D3D_OK;
+ }
+ else
+ {
+ return NOTAVAILABLE();
+ }
+ case D3DRTYPE_INDEXBUFFER:
+ switch(checkFormat)
+ {
+ case D3DFMT_INDEX16:
+ case D3DFMT_INDEX32:
+ return D3D_OK;
+ default:
+ return NOTAVAILABLE();
+ };
+ default:
+ return NOTAVAILABLE();
+ }
+ }
+
+ long Direct3D9::CheckDeviceFormatConversion(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT sourceFormat, D3DFORMAT targetFormat)
+ {
+ TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DFORMAT sourceFormat = %d, D3DFORMAT targetFormat = %d", adapter, deviceType, sourceFormat, targetFormat);
+
+ if(deviceType != D3DDEVTYPE_HAL)
+ {
+ loadSystemD3D9();
+
+ if(d3d9)
+ {
+ return d3d9->CheckDeviceFormatConversion(adapter, deviceType, sourceFormat, targetFormat);
+ }
+ else
+ {
+ return CheckDeviceFormatConversion(adapter, D3DDEVTYPE_HAL, sourceFormat, targetFormat);
+ }
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3D9::CheckDeviceMultiSampleType(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT surfaceFormat, int windowed, D3DMULTISAMPLE_TYPE multiSampleType, unsigned long *qualityLevels)
+ {
+ TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DFORMAT surfaceFormat = %d, int windowed = %d, D3DMULTISAMPLE_TYPE multiSampleType = %d, unsigned long *qualityLevels = 0x%0.8p", adapter, deviceType, surfaceFormat, windowed, multiSampleType, qualityLevels);
+
+ if(deviceType != D3DDEVTYPE_HAL)
+ {
+ loadSystemD3D9();
+
+ if(d3d9)
+ {
+ return d3d9->CheckDeviceMultiSampleType(adapter, deviceType, surfaceFormat, windowed, multiSampleType, qualityLevels);
+ }
+ else
+ {
+ return CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, surfaceFormat, windowed, multiSampleType, qualityLevels);
+ }
+ }
+
+ if(adapter >= GetAdapterCount())
+ {
+ return INVALIDCALL();
+ }
+
+ if(qualityLevels)
+ {
+ if(multiSampleType == D3DMULTISAMPLE_NONMASKABLE)
+ {
+ *qualityLevels = 4; // 2, 4, 8, 16 samples
+ }
+ else
+ {
+ *qualityLevels = 1;
+ }
+ }
+
+ if(multiSampleType == D3DMULTISAMPLE_NONE ||
+ multiSampleType == D3DMULTISAMPLE_NONMASKABLE ||
+ multiSampleType == D3DMULTISAMPLE_2_SAMPLES ||
+ multiSampleType == D3DMULTISAMPLE_4_SAMPLES ||
+ multiSampleType == D3DMULTISAMPLE_8_SAMPLES ||
+ multiSampleType == D3DMULTISAMPLE_16_SAMPLES)
+ {
+ if(CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, surfaceFormat) == D3D_OK ||
+ CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, surfaceFormat) == D3D_OK)
+ {
+ if(surfaceFormat != D3DFMT_D32F_LOCKABLE && surfaceFormat != D3DFMT_D16_LOCKABLE)
+ {
+ return D3D_OK;
+ }
+ }
+ }
+
+ return NOTAVAILABLE();
+ }
+
+ long Direct3D9::CheckDeviceType(unsigned int adapter, D3DDEVTYPE checkType, D3DFORMAT displayFormat, D3DFORMAT backBufferFormat, int windowed)
+ {
+ TRACE("unsigned int adapter = %d, D3DDEVTYPE checkType = %d, D3DFORMAT displayFormat = %d, D3DFORMAT backBufferFormat = %d, int windowed = %d", adapter, checkType, displayFormat, backBufferFormat, windowed);
+
+ if(checkType != D3DDEVTYPE_HAL)
+ {
+ loadSystemD3D9();
+
+ if(d3d9)
+ {
+ return d3d9->CheckDeviceType(adapter, checkType, displayFormat, backBufferFormat, windowed);
+ }
+ else
+ {
+ return CheckDeviceType(adapter, D3DDEVTYPE_HAL, displayFormat, backBufferFormat, windowed);
+ }
+ }
+
+ if(adapter >= GetAdapterCount())
+ {
+ return INVALIDCALL();
+ }
+
+ switch(displayFormat)
+ {
+ case D3DFMT_UNKNOWN:
+ if(windowed == FALSE)
+ {
+ return INVALIDCALL();
+ }
+ else
+ {
+ return NOTAVAILABLE();
+ }
+ case D3DFMT_A2R10G10B10:
+ case D3DFMT_A2B10G10R10:
+ if(disable10BitMode)
+ {
+ return NOTAVAILABLE();
+ }
+ case D3DFMT_X8R8G8B8:
+ case D3DFMT_R5G6B5:
+ break;
+ default:
+ return NOTAVAILABLE();
+ }
+
+ if(windowed != FALSE)
+ {
+ switch(backBufferFormat)
+ {
+ case D3DFMT_A2R10G10B10:
+ case D3DFMT_A2B10G10R10:
+ if(disable10BitMode)
+ {
+ return NOTAVAILABLE();
+ }
+ case D3DFMT_A8R8G8B8:
+ if(disableAlphaMode)
+ {
+ return NOTAVAILABLE();
+ }
+ case D3DFMT_UNKNOWN:
+ case D3DFMT_X8R8G8B8:
+ case D3DFMT_R5G6B5:
+ // case D3DFMT_X1R5G5B5: // FIXME: Supported by REF
+ // case D3DFMT_A1R5G5B5: // FIXME: Supported by REF
+ break;
+ default:
+ return NOTAVAILABLE();
+ }
+ }
+ else
+ {
+ switch(backBufferFormat)
+ {
+ case D3DFMT_UNKNOWN:
+ return INVALIDCALL();
+ case D3DFMT_A2R10G10B10:
+ case D3DFMT_A2B10G10R10:
+ if(disable10BitMode)
+ {
+ return NOTAVAILABLE();
+ }
+ case D3DFMT_A8R8G8B8:
+ if(disableAlphaMode)
+ {
+ return NOTAVAILABLE();
+ }
+ case D3DFMT_X8R8G8B8:
+ break;
+ default:
+ return NOTAVAILABLE();
+ }
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3D9::CreateDevice(unsigned int adapter, D3DDEVTYPE deviceType, HWND focusWindow, unsigned long behaviorFlags, D3DPRESENT_PARAMETERS *presentParameters, IDirect3DDevice9 **returnedDeviceInterface)
+ {
+ TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, HWND focusWindow = %d, unsigned long behaviorFlags = 0x%0.8X, D3DPRESENT_PARAMETERS *presentParameters = 0x%0.8p, IDirect3DDevice9 **returnedDeviceInterface = 0x%0.8p", adapter, deviceType, focusWindow, behaviorFlags, presentParameters, returnedDeviceInterface);
+
+ if(deviceType != D3DDEVTYPE_HAL)
+ {
+ loadSystemD3D9();
+
+ if(d3d9)
+ {
+ return d3d9->CreateDevice(adapter, deviceType, focusWindow, behaviorFlags, presentParameters, returnedDeviceInterface);
+ }
+ else
+ {
+ return CreateDevice(adapter, D3DDEVTYPE_HAL, focusWindow, behaviorFlags, presentParameters, returnedDeviceInterface);
+ }
+ }
+
+ if(!focusWindow || !presentParameters || !returnedDeviceInterface)
+ {
+ *returnedDeviceInterface = 0;
+
+ return INVALIDCALL();
+ }
+
+ *returnedDeviceInterface = new Direct3DDevice9(instance, this, adapter, deviceType, focusWindow, behaviorFlags, presentParameters);
+
+ if(*returnedDeviceInterface)
+ {
+ (*returnedDeviceInterface)->AddRef();
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3D9::EnumAdapterModes(unsigned int adapter, D3DFORMAT format, unsigned int index, D3DDISPLAYMODE *mode)
+ {
+ TRACE("unsigned int adapter = %d, D3DFORMAT format = %d, unsigned int index = %d, D3DDISPLAYMODE *mode = 0x%0.8p", adapter, format, index, mode);
+
+ if(adapter != D3DADAPTER_DEFAULT || !mode)
+ {
+ return INVALIDCALL();
+ }
+
+ unsigned int bpp = 32;
+
+ switch(format)
+ {
+ case D3DFMT_A1R5G5B5: bpp = 16; break;
+ case D3DFMT_A2R10G10B10: bpp = 32; break;
+ case D3DFMT_A8R8G8B8: bpp = 32; break;
+ case D3DFMT_R5G6B5: bpp = 16; break;
+ case D3DFMT_X1R5G5B5: bpp = 16; break;
+ case D3DFMT_X8R8G8B8: bpp = 32; break;
+ default: return INVALIDCALL();
+ }
+
+ for(int i = 0; i < numDisplayModes; i++)
+ {
+ if(displayMode[i].dmBitsPerPel == bpp)
+ {
+ if(index-- == 0)
+ {
+ mode->Width = displayMode[i].dmPelsWidth;
+ mode->Height = displayMode[i].dmPelsHeight;
+ mode->RefreshRate = displayMode[i].dmDisplayFrequency;
+ mode->Format = format;
+
+ return D3D_OK;
+ }
+ }
+ }
+
+ return INVALIDCALL();
+ }
+
+ unsigned int Direct3D9::GetAdapterCount()
+ {
+ TRACE("void");
+
+ return 1; // SwiftShader does not support multiple display adapters
+ }
+
+ long Direct3D9::GetAdapterDisplayMode(unsigned int adapter, D3DDISPLAYMODE *mode)
+ {
+ TRACE("unsigned int adapter = %d, D3DDISPLAYMODE *mode = 0x%0.8p", adapter, mode);
+
+ if(adapter != D3DADAPTER_DEFAULT || !mode)
+ {
+ return INVALIDCALL();
+ }
+
+ HDC deviceContext = GetDC(0);
+
+ mode->Width = ::GetDeviceCaps(deviceContext, HORZRES);
+ mode->Height = ::GetDeviceCaps(deviceContext, VERTRES);
+ mode->RefreshRate = ::GetDeviceCaps(deviceContext, VREFRESH);
+ unsigned int bpp = ::GetDeviceCaps(deviceContext, BITSPIXEL);
+
+ ReleaseDC(0, deviceContext);
+
+ bpp = 32; // FIXME
+
+ switch(bpp)
+ {
+ case 32: mode->Format = D3DFMT_X8R8G8B8; break;
+ case 24: mode->Format = D3DFMT_R8G8B8; break;
+ case 16: mode->Format = D3DFMT_R5G6B5; break;
+ default:
+ ASSERT(false); // Unexpected display mode color depth
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3D9::GetAdapterIdentifier(unsigned int adapter, unsigned long flags, D3DADAPTER_IDENTIFIER9 *identifier)
+ {
+ TRACE("unsigned int adapter = %d, unsigned long flags = 0x%0.8X, D3DADAPTER_IDENTIFIER9 *identifier = 0x%0.8p", adapter, flags, identifier);
+
+ if(!identifier)
+ {
+ return INVALIDCALL();
+ }
+
+ sw::Configurator ini("SwiftShader.ini");
+ int id = ini.getInteger("Capabilities", "Identifier", 0);
+
+ if(id == 1)
+ {
+ unsigned short product = 6;
+ unsigned short version = 14;
+ unsigned short subVersion = 10;
+ unsigned short revision = 8440;
+ GUID guid = {0xD7B71E3E, 0x41D2, 0x11CF, {0x96, 0x53, 0x7A, 0x23, 0x00, 0xC2, 0xCB, 0x35}};
+
+ identifier->DriverVersion.HighPart = product << 16 | version;
+ identifier->DriverVersion.LowPart = subVersion << 16 | revision;
+ strcpy(identifier->Driver, "nv4_disp.dll");
+ strcpy(identifier->Description, "NVIDIA GeForce 7900 GS");
+ strcpy(identifier->DeviceName, "\\\\.\\DISPLAY1");
+ identifier->VendorId = 0x10DE;
+ identifier->DeviceId = 0x0292;
+ identifier->SubSysId = 0x037010DE;
+ identifier->Revision = 0x00A1;
+ identifier->DeviceIdentifier = guid;
+ identifier->WHQLLevel = 1;
+
+ return D3D_OK;
+ }
+ else if(id == 2)
+ {
+ unsigned short product = 7;
+ unsigned short version = 14;
+ unsigned short subVersion = 10;
+ unsigned short revision = 464;
+ GUID guid = {0xD7B71EE2, 0x3285, 0x11CF, {0x11, 0x72, 0x0D, 0xA2, 0xA1, 0xC2, 0xCA, 0x35}};
+
+ identifier->DriverVersion.HighPart = product << 16 | version;
+ identifier->DriverVersion.LowPart = subVersion << 16 | revision;
+ strcpy(identifier->Driver, "atiumdag.dll");
+ strcpy(identifier->Description, "ATI Mobility Radeon X1600");
+ strcpy(identifier->DeviceName, "\\\\.\\DISPLAY1");
+ identifier->VendorId = 0x1002;
+ identifier->DeviceId = 0x71C5;
+ identifier->SubSysId = 0x82071071;
+ identifier->Revision = 0x0000;
+ identifier->DeviceIdentifier = guid;
+ identifier->WHQLLevel = 1;
+
+ return D3D_OK;
+ }
+ else if(id == 3)
+ {
+ unsigned short product = 7;
+ unsigned short version = 14;
+ unsigned short subVersion = 10;
+ unsigned short revision = 1437;
+ GUID guid = {0xD7B78E66, 0x6942, 0x11CF, {0x05, 0x76, 0x03, 0x22, 0xAD, 0xC2, 0xCA, 0x35}};
+
+ identifier->DriverVersion.HighPart = product << 16 | version;
+ identifier->DriverVersion.LowPart = subVersion << 16 | revision;
+ strcpy(identifier->Driver, "igdumd64.dll");
+ strcpy(identifier->Description, "Intel GMA X3100");
+ strcpy(identifier->DeviceName, "\\\\.\\DISPLAY1");
+ identifier->VendorId = 0x8086;
+ identifier->DeviceId = 0x2A02;
+ identifier->SubSysId = 0x02091028;
+ identifier->Revision = 0x000C;
+ identifier->DeviceIdentifier = guid;
+ identifier->WHQLLevel = 1;
+
+ return D3D_OK;
+ }
+ else if(id == 4)
+ {
+ loadSystemD3D9();
+
+ if(d3d9)
+ {
+ return d3d9->GetAdapterIdentifier(adapter, flags, identifier);
+ }
+ }
+
+ unsigned short product = 'sw';
+ unsigned short version = 3;
+ unsigned short subVersion = 0;
+ unsigned short revision = BUILD_REVISION;
+ GUID guid = {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
+
+ identifier->DriverVersion.HighPart = product << 16 | version;
+ identifier->DriverVersion.LowPart = subVersion << 16 | revision;
+ strcpy(identifier->Driver, "SwiftShader");
+ strcpy(identifier->Description, "TransGaming SwiftShader Software 3D Renderer");
+ strcpy(identifier->DeviceName, "\\\\.\\DISPLAY1");
+ identifier->VendorId = 0;
+ identifier->DeviceId = 0;
+ identifier->SubSysId = 0;
+ identifier->Revision = 0;
+ identifier->DeviceIdentifier = guid;
+ identifier->WHQLLevel = 0;
+
+ char exeName[MAX_PATH + 1];
+ int n = GetModuleBaseName(GetCurrentProcess(), 0, exeName, MAX_PATH);
+ exeName[n] = '\0';
+
+ if(strncmp(exeName, "Fallout", 7) == 0)
+ {
+ strcpy(identifier->Driver, "nv4_disp.dll");
+ }
+
+ return D3D_OK;
+ }
+
+ unsigned int Direct3D9::GetAdapterModeCount(unsigned int adapter, D3DFORMAT format)
+ {
+ TRACE("unsigned int adapter = %d, D3DFORMAT format = %d", adapter, format);
+
+ if(adapter != D3DADAPTER_DEFAULT)
+ {
+ return 0;
+ }
+
+ int modeCount = 0;
+
+ for(int i = 0; i < numDisplayModes; i++)
+ {
+ switch(format)
+ {
+ case D3DFMT_A8R8G8B8:
+ if(!disableAlphaMode)
+ {
+ if(displayMode[i].dmBitsPerPel == 32) modeCount++;
+ }
+ break;
+ case D3DFMT_X8R8G8B8: if(displayMode[i].dmBitsPerPel == 32) modeCount++; break;
+ case D3DFMT_A2R10G10B10:
+ case D3DFMT_A2B10G10R10:
+ if(!disable10BitMode)
+ {
+ if(displayMode[i].dmBitsPerPel == 32) modeCount++;
+ }
+ break;
+ // case D3DFMT_R8G8B8: if(displayMode[i].dmBitsPerPel == 24) modeCount++; break; // NOTE: Deprecated by DirectX 9
+ case D3DFMT_R5G6B5: if(displayMode[i].dmBitsPerPel == 16) modeCount++; break;
+ // case D3DFMT_X1R5G5B5: if(displayMode[i].dmBitsPerPel == 16) modeCount++; break;
+ // case D3DFMT_A1R5G5B5: if(displayMode[i].dmBitsPerPel == 16) modeCount++; break;
+ // default:
+ // ASSERT(false);
+ }
+ }
+
+ return modeCount;
+ }
+
+ HMONITOR Direct3D9::GetAdapterMonitor(unsigned int adapter)
+ {
+ TRACE("unsigned int adapter = %d", adapter);
+
+ POINT point = {0, 0};
+
+ return MonitorFromPoint(point, MONITOR_DEFAULTTOPRIMARY); // FIXME: Ignores adapter parameter
+ }
+
+ long Direct3D9::GetDeviceCaps(unsigned int adapter, D3DDEVTYPE deviceType, D3DCAPS9 *capabilities)
+ {
+ TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DCAPS9 *capabilities = 0x%0.8p", adapter, deviceType, capabilities);
+
+ if(deviceType != D3DDEVTYPE_HAL)
+ {
+ loadSystemD3D9();
+
+ if(d3d9)
+ {
+ return d3d9->GetDeviceCaps(adapter, deviceType, capabilities);
+ }
+ else
+ {
+ return GetDeviceCaps(adapter, D3DDEVTYPE_HAL, capabilities);
+ }
+ }
+
+ if(!capabilities)
+ {
+ return INVALIDCALL();
+ }
+
+ unsigned int pixelShaderVersion = pixelShaderVersionX;
+ unsigned int vertexShaderVersion = vertexShaderVersionX;
+
+ if(pixelShaderVersion == D3DPS_VERSION(2, 1)) pixelShaderVersion = D3DPS_VERSION(2, 0);
+ if(vertexShaderVersion == D3DVS_VERSION(2, 1)) vertexShaderVersion = D3DVS_VERSION(2, 0);
+
+ unsigned int maximumVertexShaderInstructionsExecuted = 0;
+ unsigned int maximumPixelShaderInstructionsExecuted = 0;
+ unsigned int maximumVertexShader30InstructionSlots = 0;
+ unsigned int maximumPixelShader30InstructionSlots = 0;
+
+ if(vertexShaderVersion >= D3DVS_VERSION(1, 0)) maximumVertexShaderInstructionsExecuted = 0xFFFFFFFF;
+ if(pixelShaderVersion >= D3DPS_VERSION(1, 0)) maximumPixelShaderInstructionsExecuted = 0xFFFFFFFF;
+ if(vertexShaderVersion >= D3DVS_VERSION(3, 0)) maximumVertexShader30InstructionSlots = 32768;
+ if(pixelShaderVersion >= D3DPS_VERSION(3, 0)) maximumPixelShader30InstructionSlots = 32768;
+
+ D3DCAPS9 caps;
+ ZeroMemory(&caps, sizeof(D3DCAPS9));
+
+ // Device info
+ caps.DeviceType = D3DDEVTYPE_HAL;
+ caps.AdapterOrdinal = D3DADAPTER_DEFAULT;
+
+ // Caps from DX7
+ caps.Caps = D3DCAPS_READ_SCANLINE;
+
+ caps.Caps2 = D3DCAPS2_CANAUTOGENMIPMAP | // The driver is capable of automatically generating mipmaps. For more information, see Automatic Generation of Mipmaps.
+ // D3DCAPS2_CANCALIBRATEGAMMA | // The system has a calibrator installed that can automatically adjust the gamma ramp so that the result is identical on all systems that have a calibrator. To invoke the calibrator when setting new gamma levels, use the D3DSGR_CALIBRATE flag when calling IDirect3DDevice9::SetGammaRamp. Calibrating gamma ramps incurs some processing overhead and should not be used frequently.
+ // D3DCAPS2_CANMANAGERESOURCE | // The driver is capable of managing resources. On such drivers, D3DPOOL_MANAGED resources will be managed by the driver. To have Microsoft® Direct3D® override the driver so that Direct3D manages resources, use the D3DCREATE_DISABLE_DRIVER_MANAGEMENT flag when calling IDirect3D9::CreateDevice.
+ D3DCAPS2_DYNAMICTEXTURES | // The driver supports dynamic textures.
+ D3DCAPS2_FULLSCREENGAMMA; // The driver supports dynamic gamma ramp adjustment in full-screen mode.
+ // D3DCAPS2_CANSHARERESOURCE;
+
+ caps.Caps3 = D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD | // Indicates that the device can respect the D3DRS_ALPHABLENDENABLE render state in full-screen mode while using the FLIP or DISCARD swap effect.
+ D3DCAPS3_COPY_TO_VIDMEM | // Device can accelerate a memory copy from system memory to local video memory.
+ D3DCAPS3_COPY_TO_SYSTEMMEM; // Device can accelerate a memory copy from local video memory to system memory.
+ // D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION; // Indicates that the device can perform gamma correction from a windowed back buffer (containing linear content) to an sRGB desktop.
+
+ caps.PresentationIntervals = D3DPRESENT_INTERVAL_IMMEDIATE |
+ D3DPRESENT_INTERVAL_ONE;
+ // D3DPRESENT_INTERVAL_TWO;
+ // D3DPRESENT_INTERVAL_THREE;
+ // D3DPRESENT_INTERVAL_FOUR;
+
+ // Cursor caps
+ caps.CursorCaps = D3DCURSORCAPS_COLOR | // A full-color cursor is supported in hardware. Specifically, this flag indicates that the driver supports at least a hardware color cursor in high-resolution modes (with scan lines greater than or equal to 400).
+ D3DCURSORCAPS_LOWRES; // A full-color cursor is supported in hardware. Specifically, this flag indicates that the driver supports a hardware color cursor in both high-resolution and low-resolution modes (with scan lines less than 400).
+
+ // 3D Device caps
+ caps.DevCaps = D3DDEVCAPS_CANBLTSYSTONONLOCAL | // Device supports blits from system-memory textures to nonlocal video-memory textures.
+ D3DDEVCAPS_CANRENDERAFTERFLIP | // Device can queue rendering commands after a page flip. Applications do not change their behavior if this flag is set; this capability means that the device is relatively fast.
+ D3DDEVCAPS_DRAWPRIMITIVES2 | // Device can support DrawPrimitives2.
+ D3DDEVCAPS_DRAWPRIMITIVES2EX | // Device can support extended DrawPrimitives2; that is, this is a DirectX 7.0-compliant driver.
+ D3DDEVCAPS_DRAWPRIMTLVERTEX | // Device exports an IDirect3DDevice9::DrawPrimitive-aware hardware abstraction layer (HAL).
+ D3DDEVCAPS_EXECUTESYSTEMMEMORY | // Device can use execute buffers from system memory.
+ D3DDEVCAPS_EXECUTEVIDEOMEMORY | // Device can use execute buffers from video memory.
+ D3DDEVCAPS_HWRASTERIZATION | // Device has hardware acceleration for scene rasterization.
+ D3DDEVCAPS_HWTRANSFORMANDLIGHT | // Device can support transformation and lighting in hardware.
+ // D3DDEVCAPS_NPATCHES | // Device supports N patches.
+ D3DDEVCAPS_PUREDEVICE | // Device can support rasterization, transform, lighting, and shading in hardware.
+ // D3DDEVCAPS_QUINTICRTPATCHES | // Device supports quintic Bézier curves and B-splines.
+ // D3DDEVCAPS_RTPATCHES | // Device supports rectangular and triangular patches.
+ D3DDEVCAPS_RTPATCHHANDLEZERO | // When this device capability is set, the hardware architecture does not require caching of any information and uncached patches (handle zero) will be drawn as efficiently as cached ones. Note that setting D3DDEVCAPS_RTPATCHHANDLEZERO does not mean that a patch with handle zero can be drawn. A handle-zero patch can always be drawn whether this cap is set or not.
+ // D3DDEVCAPS_SEPARATETEXTUREMEMORIES | // Device is texturing from separate memory pools.
+ D3DDEVCAPS_TEXTURENONLOCALVIDMEM | // Device can retrieve textures from non-local video memory.
+ D3DDEVCAPS_TEXTURESYSTEMMEMORY | // Device can retrieve textures from system memory.
+ D3DDEVCAPS_TEXTUREVIDEOMEMORY | // Device can retrieve textures from device memory.
+ D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | // Device can use buffers from system memory for transformed and lit vertices.
+ D3DDEVCAPS_TLVERTEXVIDEOMEMORY; // Device can use buffers from video memory for transformed and lit vertices.
+
+ caps.PrimitiveMiscCaps = D3DPMISCCAPS_MASKZ | // Device can enable and disable modification of the depth buffer on pixel operations.
+ D3DPMISCCAPS_CULLNONE | // The driver does not perform triangle culling. This corresponds to the D3DCULL_NONE member of the D3DCULL enumerated type.
+ D3DPMISCCAPS_CULLCW | // The driver supports clockwise triangle culling through the D3DRS_CULLMODE state. (This applies only to triangle primitives.) This flag corresponds to the D3DCULL_CW member of the D3DCULL enumerated type.
+ D3DPMISCCAPS_CULLCCW | // The driver supports counterclockwise culling through the D3DRS_CULLMODE state. (This applies only to triangle primitives.) This flag corresponds to the D3DCULL_CCW member of the D3DCULL enumerated type.
+ D3DPMISCCAPS_COLORWRITEENABLE | // Device supports per-channel writes for the render-target color buffer through the D3DRS_COLORWRITEENABLE state.
+ D3DPMISCCAPS_CLIPPLANESCALEDPOINTS | // Device correctly clips scaled points of size greater than 1.0 to user-defined clipping planes.
+ D3DPMISCCAPS_CLIPTLVERTS | // Device clips post-transformed vertex primitives. Specify D3DUSAGE_DONOTCLIP when the pipeline should not do any clipping. For this case, additional software clipping may need to be performed at draw time, requiring the vertex buffer to be in system memory.
+ D3DPMISCCAPS_TSSARGTEMP | // Device supports D3DTA for temporary register.
+ D3DPMISCCAPS_BLENDOP | // Device supports alpha-blending operations other than D3DBLENDOP_ADD.
+ // D3DPMISCCAPS_NULLREFERENCE | // A reference device that does not render.
+ D3DPMISCCAPS_INDEPENDENTWRITEMASKS | // Device supports independent write masks for multiple element textures or multiple render targets.
+ D3DPMISCCAPS_PERSTAGECONSTANT | // Device supports per-stage constants. See D3DTSS_CONSTANT in D3DTEXTURESTAGESTATETYPE.
+ D3DPMISCCAPS_FOGANDSPECULARALPHA | // Device supports separate fog and specular alpha. Many devices use the specular alpha channel to store the fog factor.
+ D3DPMISCCAPS_SEPARATEALPHABLEND | // Device supports separate blend settings for the alpha channel.
+ D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS | // Device supports different bit depths for multiple render targets.
+ D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING | // Device supports post-pixel shader operations for multiple render targets.
+ D3DPMISCCAPS_FOGVERTEXCLAMPED; // Device clamps fog blend factor per vertex.
+
+ caps.RasterCaps = D3DPRASTERCAPS_ANISOTROPY | // Device supports anisotropic filtering.
+ D3DPRASTERCAPS_COLORPERSPECTIVE | // Device iterates colors perspective correctly.
+ // D3DPRASTERCAPS_DITHER | // Device can dither to improve color resolution.
+ D3DPRASTERCAPS_DEPTHBIAS | // Device supports legacy depth bias. For true depth bias, see D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS.
+ D3DPRASTERCAPS_FOGRANGE | // Device supports range-based fog. In range-based fog, the distance of an object from the viewer is used to compute fog effects, not the depth of the object (that is, the z-coordinate) in the scene.
+ D3DPRASTERCAPS_FOGTABLE | // Device calculates the fog value by referring to a lookup table containing fog values that are indexed to the depth of a given pixel.
+ D3DPRASTERCAPS_FOGVERTEX | // Device calculates the fog value during the lighting operation and interpolates the fog value during rasterization.
+ D3DPRASTERCAPS_MIPMAPLODBIAS | // Device supports level of detail (LOD) bias adjustments. These bias adjustments enable an application to make a mipmap appear crisper or less sharp than it normally would. For more information about LOD bias in mipmaps, see D3DSAMP_MIPMAPLODBIAS.
+ // D3DPRASTERCAPS_MULTISAMPLE_TOGGLE | // Device supports toggling multisampling on and off between IDirect3DDevice9::BeginScene and IDirect3DDevice9::EndScene (using D3DRS_MULTISAMPLEANTIALIAS).
+ D3DPRASTERCAPS_SCISSORTEST | // Device supports scissor test. See Scissor Test.
+ D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS | // Device performs true slope-scale based depth bias. This is in contrast to the legacy style D3DPRASTERCAPS_DEPTHBIAS.
+ // D3DPRASTERCAPS_WBUFFER | // Device supports depth buffering using w.
+ D3DPRASTERCAPS_WFOG | // Device supports w-based fog. W-based fog is used when a perspective projection matrix is specified, but affine projections still use z-based fog. The system considers a projection matrix that contains a nonzero value in the [3][4] element to be a perspective projection matrix.
+ // D3DPRASTERCAPS_ZBUFFERLESSHSR | // Device can perform hidden-surface removal (HSR) without requiring the application to sort polygons and without requiring the allocation of a depth-buffer. This leaves more video memory for textures. The method used to perform HSR is hardware-dependent and is transparent to the application. Z-bufferless HSR is performed if no depth-buffer surface is associated with the rendering-target surface and the depth-buffer comparison test is enabled (that is, when the state value associated with the D3DRS_ZENABLE enumeration constant is set to TRUE).
+ D3DPRASTERCAPS_ZFOG | // Device supports z-based fog.
+ D3DPRASTERCAPS_ZTEST; // Device can perform z-test operations. This effectively renders a primitive and indicates whether any z pixels have been rendered.
+
+ caps.ZCmpCaps = D3DPCMPCAPS_ALWAYS | // Always pass the z-test.
+ D3DPCMPCAPS_EQUAL | // Pass the z-test if the new z equals the current z.
+ D3DPCMPCAPS_GREATER | // Pass the z-test if the new z is greater than the current z.
+ D3DPCMPCAPS_GREATEREQUAL | // Pass the z-test if the new z is greater than or equal to the current z.
+ D3DPCMPCAPS_LESS | // Pass the z-test if the new z is less than the current z.
+ D3DPCMPCAPS_LESSEQUAL | // Pass the z-test if the new z is less than or equal to the current z.
+ D3DPCMPCAPS_NEVER | // Always fail the z-test.
+ D3DPCMPCAPS_NOTEQUAL; // Pass the z-test if the new z does not equal the current z.
+
+ caps.SrcBlendCaps = D3DPBLENDCAPS_BLENDFACTOR | // The driver supports both D3DBLEND_BLENDFACTOR and D3DBLEND_INVBLENDFACTOR. See D3DBLEND.
+ D3DPBLENDCAPS_BOTHINVSRCALPHA | // Source blend factor is (1-As,1-As,1-As,1-As) and destination blend factor is (As,As,As,As); the destination blend selection is overridden.
+ D3DPBLENDCAPS_BOTHSRCALPHA | // The driver supports the D3DBLEND_BOTHSRCALPHA blend mode. (This blend mode is obsolete. For more information, see D3DBLEND.)
+ D3DPBLENDCAPS_DESTALPHA | // Blend factor is (Ad, Ad, Ad, Ad).
+ D3DPBLENDCAPS_DESTCOLOR | // Blend factor is (Rd, Gd, Bd, Ad).
+ D3DPBLENDCAPS_INVDESTALPHA | // Blend factor is (1-Ad, 1-Ad, 1-Ad, 1-Ad).
+ D3DPBLENDCAPS_INVDESTCOLOR | // Blend factor is (1-Rd, 1-Gd, 1-Bd, 1-Ad).
+ D3DPBLENDCAPS_INVSRCALPHA | // Blend factor is (1-As, 1-As, 1-As, 1-As).
+ D3DPBLENDCAPS_INVSRCCOLOR | // Blend factor is (1-Rs, 1-Gs, 1-Bs, 1-As).
+ D3DPBLENDCAPS_ONE | // Blend factor is (1, 1, 1, 1).
+ D3DPBLENDCAPS_SRCALPHA | // Blend factor is (As, As, As, As).
+ D3DPBLENDCAPS_SRCALPHASAT | // Blend factor is (f, f, f, 1); f = min(As, 1-Ad).
+ D3DPBLENDCAPS_SRCCOLOR | // Blend factor is (Rs, Gs, Bs, As).
+ D3DPBLENDCAPS_ZERO; // Blend factor is (0, 0, 0, 0).
+
+ caps.DestBlendCaps = D3DPBLENDCAPS_BLENDFACTOR | // The driver supports both D3DBLEND_BLENDFACTOR and D3DBLEND_INVBLENDFACTOR. See D3DBLEND.
+ D3DPBLENDCAPS_BOTHINVSRCALPHA | // Source blend factor is (1-As,1-As,1-As,1-As) and destination blend factor is (As,As,As,As); the destination blend selection is overridden.
+ D3DPBLENDCAPS_BOTHSRCALPHA | // The driver supports the D3DBLEND_BOTHSRCALPHA blend mode. (This blend mode is obsolete. For more information, see D3DBLEND.)
+ D3DPBLENDCAPS_DESTALPHA | // Blend factor is (Ad, Ad, Ad, Ad).
+ D3DPBLENDCAPS_DESTCOLOR | // Blend factor is (Rd, Gd, Bd, Ad).
+ D3DPBLENDCAPS_INVDESTALPHA | // Blend factor is (1-Ad, 1-Ad, 1-Ad, 1-Ad).
+ D3DPBLENDCAPS_INVDESTCOLOR | // Blend factor is (1-Rd, 1-Gd, 1-Bd, 1-Ad).
+ D3DPBLENDCAPS_INVSRCALPHA | // Blend factor is (1-As, 1-As, 1-As, 1-As).
+ D3DPBLENDCAPS_INVSRCCOLOR | // Blend factor is (1-Rs, 1-Gs, 1-Bs, 1-As).
+ D3DPBLENDCAPS_ONE | // Blend factor is (1, 1, 1, 1).
+ D3DPBLENDCAPS_SRCALPHA | // Blend factor is (As, As, As, As).
+ D3DPBLENDCAPS_SRCALPHASAT | // Blend factor is (f, f, f, 1); f = min(As, 1-Ad).
+ D3DPBLENDCAPS_SRCCOLOR | // Blend factor is (Rs, Gs, Bs, As).
+ D3DPBLENDCAPS_ZERO; // Blend factor is (0, 0, 0, 0).
+
+ caps.AlphaCmpCaps = D3DPCMPCAPS_ALWAYS | // Always pass the apha-test.
+ D3DPCMPCAPS_EQUAL | // Pass the apha-test if the new apha equals the current apha.
+ D3DPCMPCAPS_GREATER | // Pass the apha-test if the new apha is greater than the current apha.
+ D3DPCMPCAPS_GREATEREQUAL | // Pass the apha-test if the new apha is greater than or equal to the current apha.
+ D3DPCMPCAPS_LESS | // Pass the apha-test if the new apha is less than the current apha.
+ D3DPCMPCAPS_LESSEQUAL | // Pass the apha-test if the new apha is less than or equal to the current apha.
+ D3DPCMPCAPS_NEVER | // Always fail the apha-test.
+ D3DPCMPCAPS_NOTEQUAL; // Pass the apha-test if the new apha does not equal the current apha.
+
+ caps.ShadeCaps = D3DPSHADECAPS_ALPHAGOURAUDBLEND | // Device can support an alpha component for Gouraud-blended transparency (the D3DSHADE_GOURAUD state for the D3DSHADEMODE enumerated type). In this mode, the alpha color component of a primitive is provided at vertices and interpolated across a face along with the other color components.
+ D3DPSHADECAPS_COLORGOURAUDRGB | // Device can support colored Gouraud shading in the RGB color model. In this mode, the color component for a primitive is provided at vertices and interpolated across a face along with the other color components. In the RGB lighting model, the red, green, and blue components are interpolated.
+ D3DPSHADECAPS_FOGGOURAUD | // Device can support fog in the Gouraud shading mode.
+ D3DPSHADECAPS_SPECULARGOURAUDRGB; // Device supports Gouraud shading of specular highlights.
+
+ caps.TextureCaps = D3DPTEXTURECAPS_ALPHA | // Alpha in texture pixels is supported.
+ D3DPTEXTURECAPS_ALPHAPALETTE | // Device can draw alpha from texture palettes.
+ D3DPTEXTURECAPS_CUBEMAP | // Supports cube textures.
+ // D3DPTEXTURECAPS_CUBEMAP_POW2 | // Device requires that cube texture maps have dimensions specified as powers of two.
+ D3DPTEXTURECAPS_MIPCUBEMAP | // Device supports mipmapped cube textures.
+ D3DPTEXTURECAPS_MIPMAP | // Device supports mipmapped textures.
+ D3DPTEXTURECAPS_MIPVOLUMEMAP | // Device supports mipmapped volume textures.
+ // D3DPTEXTURECAPS_NONPOW2CONDITIONAL | // Conditionally supports the use of 2-D textures with dimensions that are not powers of two. A device that exposes this capability can use such a texture if all of the following requirements are met...
+ // D3DPTEXTURECAPS_NOPROJECTEDBUMPENV | // Device does not support a projected bump-environment loopkup operation in programmable and fixed function shaders.
+ D3DPTEXTURECAPS_PERSPECTIVE | // Perspective correction texturing is supported.
+ // D3DPTEXTURECAPS_POW2 | // All textures must have widths and heights specified as powers of two. This requirement does not apply to either cube textures or volume textures.
+ D3DPTEXTURECAPS_PROJECTED | // Supports the D3DTTFF_PROJECTED texture transformation flag. When applied, the device divides transformed texture coordinates by the last texture coordinate. If this capability is present, then the projective divide occurs per pixel. If this capability is not present, but the projective divide needs to occur anyway, then it is performed on a per-vertex basis by the Direct3D runtime.
+ // D3DPTEXTURECAPS_SQUAREONLY | // All textures must be square.
+ D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE | // Texture indices are not scaled by the texture size prior to interpolation.
+ D3DPTEXTURECAPS_VOLUMEMAP; // Device supports volume textures.
+ // D3DPTEXTURECAPS_VOLUMEMAP_POW2; // Device requires that volume texture maps have dimensions specified as powers of two.
+
+ caps.TextureFilterCaps = D3DPTFILTERCAPS_MAGFPOINT | // Device supports per-stage point-sample filtering for magnifying textures. The point-sample magnification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+ D3DPTFILTERCAPS_MAGFLINEAR | // Device supports per-stage bilinear interpolation filtering for magnifying mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MAGFANISOTROPIC | // Device supports per-stage anisotropic filtering for magnifying textures. The anisotropic magnification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD | // Device supports per-stage pyramidal sample filtering for magnifying textures. The pyramidal magnifying filter is represented by the D3DTEXF_PYRAMIDALQUAD member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MAGFGAUSSIANQUAD | // Device supports per-stage Gaussian quad filtering for magnifying textures.
+ D3DPTFILTERCAPS_MINFPOINT | // Device supports per-stage point-sample filtering for minifying textures. The point-sample minification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+ D3DPTFILTERCAPS_MINFLINEAR | // Device supports per-stage linear filtering for minifying textures. The linear minification filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+ D3DPTFILTERCAPS_MINFANISOTROPIC | // Device supports per-stage anisotropic filtering for minifying textures. The anisotropic minification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MINFPYRAMIDALQUAD | // Device supports per-stage pyramidal sample filtering for minifying textures.
+ // D3DPTFILTERCAPS_MINFGAUSSIANQUAD | // Device supports per-stage Gaussian quad filtering for minifying textures.
+ D3DPTFILTERCAPS_MIPFPOINT | // Device supports per-stage point-sample filtering for mipmaps. The point-sample mipmapping filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+ D3DPTFILTERCAPS_MIPFLINEAR; // Device supports per-stage bilinear interpolation filtering for mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+
+ caps.CubeTextureFilterCaps = D3DPTFILTERCAPS_MAGFPOINT | // Device supports per-stage point-sample filtering for magnifying textures. The point-sample magnification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+ D3DPTFILTERCAPS_MAGFLINEAR | // Device supports per-stage bilinear interpolation filtering for magnifying mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MAGFANISOTROPIC | // Device supports per-stage anisotropic filtering for magnifying textures. The anisotropic magnification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD | // Device supports per-stage pyramidal sample filtering for magnifying textures. The pyramidal magnifying filter is represented by the D3DTEXF_PYRAMIDALQUAD member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MAGFGAUSSIANQUAD | // Device supports per-stage Gaussian quad filtering for magnifying textures.
+ D3DPTFILTERCAPS_MINFPOINT | // Device supports per-stage point-sample filtering for minifying textures. The point-sample minification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+ D3DPTFILTERCAPS_MINFLINEAR | // Device supports per-stage linear filtering for minifying textures. The linear minification filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MINFANISOTROPIC | // Device supports per-stage anisotropic filtering for minifying textures. The anisotropic minification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MINFPYRAMIDALQUAD | // Device supports per-stage pyramidal sample filtering for minifying textures.
+ // D3DPTFILTERCAPS_MINFGAUSSIANQUAD | // Device supports per-stage Gaussian quad filtering for minifying textures.
+ D3DPTFILTERCAPS_MIPFPOINT | // Device supports per-stage point-sample filtering for mipmaps. The point-sample mipmapping filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+ D3DPTFILTERCAPS_MIPFLINEAR; // Device supports per-stage bilinear interpolation filtering for mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+
+ caps.VolumeTextureFilterCaps = D3DPTFILTERCAPS_MAGFPOINT | // Device supports per-stage point-sample filtering for magnifying textures. The point-sample magnification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+ D3DPTFILTERCAPS_MAGFLINEAR | // Device supports per-stage bilinear interpolation filtering for magnifying mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MAGFANISOTROPIC | // Device supports per-stage anisotropic filtering for magnifying textures. The anisotropic magnification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD | // Device supports per-stage pyramidal sample filtering for magnifying textures. The pyramidal magnifying filter is represented by the D3DTEXF_PYRAMIDALQUAD member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MAGFGAUSSIANQUAD | // Device supports per-stage Gaussian quad filtering for magnifying textures.
+ D3DPTFILTERCAPS_MINFPOINT | // Device supports per-stage point-sample filtering for minifying textures. The point-sample minification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+ D3DPTFILTERCAPS_MINFLINEAR | // Device supports per-stage linear filtering for minifying textures. The linear minification filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MINFANISOTROPIC | // Device supports per-stage anisotropic filtering for minifying textures. The anisotropic minification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MINFPYRAMIDALQUAD | // Device supports per-stage pyramidal sample filtering for minifying textures.
+ // D3DPTFILTERCAPS_MINFGAUSSIANQUAD | // Device supports per-stage Gaussian quad filtering for minifying textures.
+ D3DPTFILTERCAPS_MIPFPOINT | // Device supports per-stage point-sample filtering for mipmaps. The point-sample mipmapping filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+ D3DPTFILTERCAPS_MIPFLINEAR; // Device supports per-stage bilinear interpolation filtering for mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+
+ caps.TextureAddressCaps = D3DPTADDRESSCAPS_BORDER | // Device supports setting coordinates outside the range [0.0, 1.0] to the border color, as specified by the D3DSAMP_BORDERCOLOR texture-stage state.
+ D3DPTADDRESSCAPS_CLAMP | // Device can clamp textures to addresses.
+ D3DPTADDRESSCAPS_INDEPENDENTUV | // Device can separate the texture-addressing modes of the u and v coordinates of the texture. This ability corresponds to the D3DSAMP_ADDRESSU and D3DSAMP_ADDRESSV render-state values.
+ D3DPTADDRESSCAPS_MIRROR | // Device can mirror textures to addresses.
+ D3DPTADDRESSCAPS_MIRRORONCE | // Device can take the absolute value of the texture coordinate (thus, mirroring around 0) and then clamp to the maximum value.
+ D3DPTADDRESSCAPS_WRAP; // Device can wrap textures to addresses.
+
+ caps.VolumeTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | // Device supports setting coordinates outside the range [0.0, 1.0] to the border color, as specified by the D3DSAMP_BORDERCOLOR texture-stage state.
+ D3DPTADDRESSCAPS_CLAMP | // Device can clamp textures to addresses.
+ D3DPTADDRESSCAPS_INDEPENDENTUV | // Device can separate the texture-addressing modes of the u and v coordinates of the texture. This ability corresponds to the D3DSAMP_ADDRESSU and D3DSAMP_ADDRESSV render-state values.
+ D3DPTADDRESSCAPS_MIRROR | // Device can mirror textures to addresses.
+ D3DPTADDRESSCAPS_MIRRORONCE | // Device can take the absolute value of the texture coordinate (thus, mirroring around 0) and then clamp to the maximum value.
+ D3DPTADDRESSCAPS_WRAP; // Device can wrap textures to addresses.
+
+ caps.LineCaps = D3DLINECAPS_ALPHACMP | // Supports alpha-test comparisons.
+ // D3DLINECAPS_ANTIALIAS | // Antialiased lines are supported.
+ D3DLINECAPS_BLEND | // Supports source-blending.
+ D3DLINECAPS_FOG | // Supports fog.
+ D3DLINECAPS_TEXTURE | // Supports texture-mapping.
+ D3DLINECAPS_ZTEST; // Supports z-buffer comparisons.
+
+ caps.MaxTextureWidth = 1 << (MIPMAP_LEVELS - 1);
+ caps.MaxTextureHeight = 1 << (MIPMAP_LEVELS - 1);
+ caps.MaxVolumeExtent = 1 << (MIPMAP_LEVELS - 1);
+ caps.MaxTextureRepeat = 8192;
+ caps.MaxTextureAspectRatio = 1 << (MIPMAP_LEVELS - 1);
+ caps.MaxAnisotropy = maxAnisotropy;
+ caps.MaxVertexW = 1e+010;
+
+ caps.GuardBandLeft = -1e+008;
+ caps.GuardBandTop = -1e+008;
+ caps.GuardBandRight = 1e+008;
+ caps.GuardBandBottom = 1e+008;
+
+ caps.ExtentsAdjust = 0;
+
+ caps.StencilCaps = D3DSTENCILCAPS_KEEP | // Do not update the entry in the stencil buffer. This is the default value.
+ D3DSTENCILCAPS_ZERO | // Set the stencil-buffer entry to 0.
+ D3DSTENCILCAPS_REPLACE | // Replace the stencil-buffer entry with reference value.
+ D3DSTENCILCAPS_INCRSAT | // Increment the stencil-buffer entry, clamping to the maximum value.
+ D3DSTENCILCAPS_DECRSAT | // Decrement the stencil-buffer entry, clamping to zero.
+ D3DSTENCILCAPS_INVERT | // Invert the bits in the stencil-buffer entry.
+ D3DSTENCILCAPS_INCR | // Increment the stencil-buffer entry, wrapping to zero if the new value exceeds the maximum value.
+ D3DSTENCILCAPS_DECR | // Decrement the stencil-buffer entry, wrapping to the maximum value if the new value is less than zero.
+ D3DSTENCILCAPS_TWOSIDED; // The device supports two-sided stencil.
+
+ caps.FVFCaps = D3DFVFCAPS_DONOTSTRIPELEMENTS | // It is preferable that vertex elements not be stripped. That is, if the vertex format contains elements that are not used with the current render states, there is no need to regenerate the vertices. If this capability flag is not present, stripping extraneous elements from the vertex format provides better performance.
+ D3DFVFCAPS_PSIZE | // Point size is determined by either the render state or the vertex data.
+ // D3DFVFCAPS_TEXCOORDCOUNTMASK | // Masks the low WORD of FVFCaps. These bits, cast to the WORD data type, describe the total number of texture coordinate sets that the device can simultaneously use for multiple texture blending. (You can use up to eight texture coordinate sets for any vertex, but the device can blend using only the specified number of texture coordinate sets.)
+ 8;
+
+ caps.TextureOpCaps = D3DTEXOPCAPS_ADD | // The D3DTOP_ADD texture-blending operation is supported.
+ D3DTEXOPCAPS_ADDSIGNED | // The D3DTOP_ADDSIGNED texture-blending operation is supported.
+ D3DTEXOPCAPS_ADDSIGNED2X | // The D3DTOP_ADDSIGNED2X texture-blending operation is supported.
+ D3DTEXOPCAPS_ADDSMOOTH | // The D3DTOP_ADDSMOOTH texture-blending operation is supported.
+ D3DTEXOPCAPS_BLENDCURRENTALPHA | // The D3DTOP_BLENDCURRENTALPHA texture-blending operation is supported.
+ D3DTEXOPCAPS_BLENDDIFFUSEALPHA | // The D3DTOP_BLENDDIFFUSEALPHA texture-blending operation is supported.
+ D3DTEXOPCAPS_BLENDFACTORALPHA | // The D3DTOP_BLENDFACTORALPHA texture-blending operation is supported.
+ D3DTEXOPCAPS_BLENDTEXTUREALPHA | // The D3DTOP_BLENDTEXTUREALPHA texture-blending operation is supported.
+ D3DTEXOPCAPS_BLENDTEXTUREALPHAPM | // The D3DTOP_BLENDTEXTUREALPHAPM texture-blending operation is supported.
+ D3DTEXOPCAPS_BUMPENVMAP | // The D3DTOP_BUMPENVMAP texture-blending operation is supported.
+ D3DTEXOPCAPS_BUMPENVMAPLUMINANCE | // The D3DTOP_BUMPENVMAPLUMINANCE texture-blending operation is supported.
+ D3DTEXOPCAPS_DISABLE | // The D3DTOP_DISABLE texture-blending operation is supported.
+ D3DTEXOPCAPS_DOTPRODUCT3 | // The D3DTOP_DOTPRODUCT3 texture-blending operation is supported.
+ D3DTEXOPCAPS_LERP | // The D3DTOP_LERP texture-blending operation is supported.
+ D3DTEXOPCAPS_MODULATE | // The D3DTOP_MODULATE texture-blending operation is supported.
+ D3DTEXOPCAPS_MODULATE2X | // The D3DTOP_MODULATE2X texture-blending operation is supported.
+ D3DTEXOPCAPS_MODULATE4X | // The D3DTOP_MODULATE4X texture-blending operation is supported.
+ D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR | // The D3DTOP_MODULATEALPHA_ADDCOLOR texture-blending operation is supported.
+ D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA | // The D3DTOP_MODULATECOLOR_ADDALPHA texture-blending operation is supported.
+ D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR | // The D3DTOP_MODULATEINVALPHA_ADDCOLOR texture-blending operation is supported.
+ D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA | // The D3DTOP_MODULATEINVCOLOR_ADDALPHA texture-blending operation is supported.
+ D3DTEXOPCAPS_MULTIPLYADD | // The D3DTOP_MULTIPLYADD texture-blending operation is supported.
+ D3DTEXOPCAPS_PREMODULATE | // The D3DTOP_PREMODULATE texture-blending operation is supported.
+ D3DTEXOPCAPS_SELECTARG1 | // The D3DTOP_SELECTARG1 texture-blending operation is supported.
+ D3DTEXOPCAPS_SELECTARG2 | // The D3DTOP_SELECTARG2 texture-blending operation is supported.
+ D3DTEXOPCAPS_SUBTRACT; // The D3DTOP_SUBTRACT texture-blending operation is supported.
+
+ caps.MaxTextureBlendStages = 8;
+ caps.MaxSimultaneousTextures = 8;
+
+ caps.VertexProcessingCaps = D3DVTXPCAPS_DIRECTIONALLIGHTS | // Device can do directional lights.
+ D3DVTXPCAPS_LOCALVIEWER | // Device can do local viewer.
+ D3DVTXPCAPS_MATERIALSOURCE7 | // Device can do Microsoft® DirectX® 7.0 colormaterialsource operations.
+ // D3DVTXPCAPS_NO_TEXGEN_NONLOCALVIEWER | // Device does not support texture generation in non-local viewer mode.
+ D3DVTXPCAPS_POSITIONALLIGHTS | // Device can do positional lights (includes point and spot).
+ D3DVTXPCAPS_TEXGEN | // Device can do texgen.
+ D3DVTXPCAPS_TEXGEN_SPHEREMAP; // Device supports D3DTSS_TCI_SPHEREMAP.
+ // D3DVTXPCAPS_TWEENING; // Device can do vertex tweening.
+
+ caps.MaxActiveLights = 8; // Maximum number of lights that can be active simultaneously. For a given physical device, this capability might vary across Direct3DDevice objects depending on the parameters supplied to IDirect3D9::CreateDevice.
+ caps.MaxUserClipPlanes = 6; // Maximum number of user-defined clipping planes supported. This member can range from 0 through D3DMAXUSERCLIPPLANES. For a given physical device, this capability may vary across Direct3DDevice objects depending on the parameters supplied to IDirect3D9::CreateDevice.
+ caps.MaxVertexBlendMatrices = 4; // Maximum number of matrices that this device can apply when performing multimatrix vertex blending. For a given physical device, this capability may vary across Direct3DDevice objects depending on the parameters supplied to IDirect3D9::CreateDevice.
+ caps.MaxVertexBlendMatrixIndex = 11; // DWORD value that specifies the maximum matrix index that can be indexed into using the per-vertex indices. The number of matrices is MaxVertexBlendMatrixIndex + 1, which is the size of the matrix palette. If normals are present in the vertex data that needs to be blended for lighting, then the number of matrices is half the number specified by this capability flag. If MaxVertexBlendMatrixIndex is set to zero, the driver does not support indexed vertex blending. If this value is not zero then the valid range of indices is zero through MaxVertexBlendMatrixIndex.
+ caps.MaxPointSize = 8192.0f; // Maximum size of a point primitive. If set to 1.0f then device does not support point size control. The range is greater than or equal to 1.0f.
+ caps.MaxPrimitiveCount = 1 << 21; // Maximum number of primitives for each IDirect3DDevice9::DrawPrimitive call. Note that when Direct3D is working with a DirectX 6.0 or DirectX 7.0 driver, this field is set to 0xFFFF. This means that not only the number of primitives but also the number of vertices is limited by this value.
+ caps.MaxVertexIndex = 1 << 24; // Maximum size of indices supported for hardware vertex processing. It is possible to create 32-bit index buffers by specifying D3DFMT_INDEX32; however, you will not be able to render with the index buffer unless this value is greater than 0x0000FFFF.
+ caps.MaxStreams = 16; // Maximum number of concurrent data streams for IDirect3DDevice9::SetStreamSource. The valid range is 1 to 16. Note that if this value is 0, then the driver is not a DirectX 9.0 driver.
+ caps.MaxStreamStride = 65536; // Maximum stride for IDirect3DDevice9::SetStreamSource.
+ caps.VertexShaderVersion = vertexShaderVersion; // Two numbers that represent the vertex shader main and sub versions. For more information about the instructions supported for each vertex shader version, see Version 1_x, Version 2_0, Version 2_0 Extended, or Version 3_0.
+ caps.MaxVertexShaderConst = 256; // The number of vertex shader Registers that are reserved for constants.
+ caps.PixelShaderVersion = pixelShaderVersion; // Two numbers that represent the pixel shader main and sub versions. For more information about the instructions supported for each pixel shader version, see Version 1_x, Version 2_0, Version 2_0 Extended, or Version 3_0.
+ caps.PixelShader1xMaxValue = 8.0; // Maximum value of pixel shader arithmetic component. This value indicates the internal range of values supported for pixel color blending operations. Within the range that they report to, implementations must allow data to pass through pixel processing unmodified (unclamped). Normally, the value of this member is an absolute value. For example, a 1.0 indicates that the range is -1.0 to 1, and an 8.0 indicates that the range is -8.0 to 8.0. The value must be >= 1.0 for any hardware that supports pixel shaders.
+
+ caps.DevCaps2 = // D3DDEVCAPS2_ADAPTIVETESSRTPATCH | // Device supports adaptive tessellation of RT-patches
+ // D3DDEVCAPS2_ADAPTIVETESSNPATCH | // Device supports adaptive tessellation of N-patches.
+ D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES | // Device supports IDirect3DDevice9::StretchRect using a texture as the source.
+ // D3DDEVCAPS2_DMAPNPATCH | // Device supports displacement maps for N-patches.
+ // D3DDEVCAPS2_PRESAMPLEDDMAPNPATCH | // Device supports presampled displacement maps for N-patches. For more information about displacement mapping, see Displacement Mapping.
+ D3DDEVCAPS2_STREAMOFFSET | // Device supports stream offsets.
+ D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET; // Multiple vertex elements can share the same offset in a stream if D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET is set by the device and the vertex declaration does not have an element with D3DDECLUSAGE_POSITIONT0.
+
+ caps.MaxNpatchTessellationLevel = 0; // Maximum number of N-patch subdivision levels. The driver will clamp applications to this value, if they are using presampled displacement mapping. See Tessellation and Displacement Mapping.
+ caps.MasterAdapterOrdinal = 0; // This number indicates which device is the master for this subordinate. This number is taken from the same space as the adapter values passed to the IDirect3D9 methods.
+ caps.AdapterOrdinalInGroup = 0; // This number indicates the order in which heads are referenced by the application programming interface (API). The master adapter always has AdapterOrdinalInGroup = 0. These values do not correspond to the adapter ordinals passed to the IDirect3D9 methods. They apply only to heads within a group.
+ caps.NumberOfAdaptersInGroup = 1; // Number of adapters in this adapter group (only if master). This will be 1 for conventional adapters. The value will be greater than 1 for the master adapter of a multihead card. The value will be 0 for a subordinate adapter of a multihead card. Each card can have at most one master, but may have many subordinates.
+
+ caps.DeclTypes = D3DDTCAPS_UBYTE4 | // 4-D unsigned byte.
+ D3DDTCAPS_UBYTE4N | // Normalized, 4-D unsigned byte. Each of the four bytes is normalized by dividing to 255.0.
+ D3DDTCAPS_SHORT2N | // Normalized, 2-D signed short, expanded to (first byte/32767.0, second byte/32767.0, 0, 1).
+ D3DDTCAPS_SHORT4N | // Normalized, 4-D signed short, expanded to (first byte/32767.0, second byte/32767.0, third byte/32767.0, fourth byte/32767.0).
+ D3DDTCAPS_USHORT2N | // Normalized, 2-D unsigned short, expanded to (first byte/65535.0, second byte/65535.0, 0, 1).
+ D3DDTCAPS_USHORT4N | // Normalized 4-D unsigned short, expanded to (first byte/65535.0, second byte/65535.0, third byte/65535.0, fourth byte/65535.0).
+ D3DDTCAPS_UDEC3 | // 3-D unsigned 10 10 10 format expanded to (value, value, value, 1).
+ D3DDTCAPS_DEC3N | // 3-D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1).
+ D3DDTCAPS_FLOAT16_2 | // 2-D 16-bit floating point numbers.
+ D3DDTCAPS_FLOAT16_4; // 4-D 16-bit floating point numbers.
+
+ caps.NumSimultaneousRTs = 4; // Number of simultaneous render targets. This number must be at least one.
+
+ caps.StretchRectFilterCaps = D3DPTFILTERCAPS_MINFPOINT | // Device supports point-sample filtering for minifying rectangles. This filter type is requested by calling IDirect3DDevice9::StretchRect using D3DTEXF_POINT.
+ D3DPTFILTERCAPS_MAGFPOINT | // Device supports point-sample filtering for magnifying rectangles. This filter type is requested by calling IDirect3DDevice9::StretchRect using D3DTEXF_POINT.
+ D3DPTFILTERCAPS_MINFLINEAR | // Device supports bilinear interpolation filtering for minifying rectangles. This filter type is requested by calling IDirect3DDevice9::StretchRect using D3DTEXF_LINEAR.
+ D3DPTFILTERCAPS_MAGFLINEAR; // Device supports bilinear interpolation filtering for magnifying rectangles. This filter type is requested by calling IDirect3DDevice9::StretchRect using D3DTEXF_LINEAR.
+
+ caps.VS20Caps.Caps = vertexShaderPredication; // Instruction predication is supported. See setp_comp.
+ caps.VS20Caps.DynamicFlowControlDepth = vertexShaderDynamicFlowControlDepth; // The maximum level of nesting of dynamic flow control instructions (break, breakc, ifc).
+ caps.VS20Caps.NumTemps = D3DVS20_MAX_NUMTEMPS; // The maximum number of temporary registers supported.
+ caps.VS20Caps.StaticFlowControlDepth = D3DVS20_MAX_STATICFLOWCONTROLDEPTH; // The maximum depth of nesting of the loop/rep and call/callnz bool instructions.
+
+ caps.PS20Caps.Caps = pixelShaderArbitrarySwizzle | // Arbitrary swizzling is supported.
+ pixelShaderGradientInstructions | // Gradient instructions are supported.
+ pixelShaderPredication | // Instruction predication is supported. See setp_comp - ps.
+ pixelShaderNoDependentReadLimit | // There is no limit on the number of dependent reads per instruction.
+ pixelShaderNoTexInstructionLimit; // There is no limit on the number of tex instructions.
+
+ caps.PS20Caps.DynamicFlowControlDepth = pixelShaderDynamicFlowControlDepth; // The maximum level of nesting of dynamic flow control instructions (break, breakc, ifc).
+ caps.PS20Caps.NumInstructionSlots = D3DPS20_MAX_NUMINSTRUCTIONSLOTS; // The driver will support at most this many instructions.
+ caps.PS20Caps.NumTemps = D3DPS20_MAX_NUMTEMPS; // The driver will support at most this many temporary register.
+ caps.PS20Caps.StaticFlowControlDepth = pixelShaderStaticFlowControlDepth; // The maximum depth of nesting of the loop/rep and call/callnz bool instructions.
+
+ caps.VertexTextureFilterCaps = D3DPTFILTERCAPS_MAGFPOINT | // Device supports per-stage point-sample filtering for magnifying textures. The point-sample magnification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MAGFLINEAR | // Device supports per-stage bilinear interpolation filtering for magnifying mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MAGFANISOTROPIC | // Device supports per-stage anisotropic filtering for magnifying textures. The anisotropic magnification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD | // Device supports per-stage pyramidal sample filtering for magnifying textures. The pyramidal magnifying filter is represented by the D3DTEXF_PYRAMIDALQUAD member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MAGFGAUSSIANQUAD | // Device supports per-stage Gaussian quad filtering for magnifying textures.
+ D3DPTFILTERCAPS_MINFPOINT | // Device supports per-stage point-sample filtering for minifying textures. The point-sample minification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MINFLINEAR | // Device supports per-stage linear filtering for minifying textures. The linear minification filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MINFANISOTROPIC | // Device supports per-stage anisotropic filtering for minifying textures. The anisotropic minification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MINFPYRAMIDALQUAD | // Device supports per-stage pyramidal sample filtering for minifying textures.
+ // D3DPTFILTERCAPS_MINFGAUSSIANQUAD | // Device supports per-stage Gaussian quad filtering for minifying textures.
+ D3DPTFILTERCAPS_MIPFPOINT; // Device supports per-stage point-sample filtering for mipmaps. The point-sample mipmapping filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
+ // D3DPTFILTERCAPS_MIPFLINEAR; // Device supports per-stage bilinear interpolation filtering for mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
+
+ caps.MaxVShaderInstructionsExecuted = maximumVertexShaderInstructionsExecuted; // Maximum number of vertex shader instructions that can be run.
+ caps.MaxPShaderInstructionsExecuted = maximumPixelShaderInstructionsExecuted; // Maximum number of pixel shader instructions that can be run.
+ caps.MaxVertexShader30InstructionSlots = maximumVertexShader30InstructionSlots; // Maximum number of vertex shader instruction slots supported. The maximum value that can be set on this cap is 32768. Devices that support vs_3_0 are required to support at least 512 instruction slots.
+ caps.MaxPixelShader30InstructionSlots = maximumPixelShader30InstructionSlots; // Maximum number of pixel shader instruction slots supported. The maximum value that can be set on this cap is 32768. Devices that support ps_3_0 are required to support at least 512 instruction slots.
+
+ *capabilities = caps;
+
+ return D3D_OK;
+ }
+
+ long Direct3D9::RegisterSoftwareDevice(void *initializeFunction)
+ {
+ TRACE("void *initializeFunction = 0x%0.8p", initializeFunction);
+
+ loadSystemD3D9();
+
+ if(d3d9)
+ {
+ return d3d9->RegisterSoftwareDevice(initializeFunction);
+ }
+ else
+ {
+ return INVALIDCALL();
+ }
+ }
+
+ void Direct3D9::loadSystemD3D9()
+ {
+ if(d3d9)
+ {
+ return;
+ }
+
+ char d3d9Path[MAX_PATH + 16];
+ GetSystemDirectory(d3d9Path, MAX_PATH);
+ strcat(d3d9Path, "\\d3d9.dll");
+ d3d9Lib = LoadLibrary(d3d9Path);
+
+ if(d3d9Lib)
+ {
+ typedef IDirect3D9* (__stdcall *DIRECT3DCREATE9)(unsigned int);
+ DIRECT3DCREATE9 direct3DCreate9 = (DIRECT3DCREATE9)GetProcAddress(d3d9Lib, "Direct3DCreate9");
+ d3d9 = direct3DCreate9(D3D_SDK_VERSION);
+ }
+ }
+}
diff --git a/src/D3D9/Direct3D9.hpp b/src/D3D9/Direct3D9.hpp
new file mode 100644
index 0000000..b38ed82
--- /dev/null
+++ b/src/D3D9/Direct3D9.hpp
@@ -0,0 +1,73 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Direct3D9_hpp
+#define D3D9_Direct3D9_hpp
+
+#include "Unknown.hpp"
+
+#include <stdio.h>
+#include <d3d9.h>
+
+namespace D3D9
+{
+ class Direct3DDevice9;
+
+ class Direct3D9 : public IDirect3D9, public Unknown
+ {
+ public:
+ Direct3D9(int version, const HINSTANCE instance);
+
+ virtual ~Direct3D9();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // IDirect3D9 methods
+ long __stdcall RegisterSoftwareDevice(void *initializeFunction);
+ unsigned int __stdcall GetAdapterCount();
+ long __stdcall GetAdapterIdentifier(unsigned int adapter, unsigned long flags, D3DADAPTER_IDENTIFIER9 *identifier);
+ unsigned int __stdcall GetAdapterModeCount(unsigned int adapter, D3DFORMAT format);
+ long __stdcall EnumAdapterModes(unsigned int adapter, D3DFORMAT format, unsigned int index, D3DDISPLAYMODE *mode);
+ long __stdcall GetAdapterDisplayMode(unsigned int adapter, D3DDISPLAYMODE *mode);
+ long __stdcall CheckDeviceType(unsigned int adapter, D3DDEVTYPE checkType, D3DFORMAT displayFormat, D3DFORMAT backBufferFormat, int windowed);
+ long __stdcall CheckDeviceFormat(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT adapterFormat, unsigned long usage, D3DRESOURCETYPE type, D3DFORMAT checkFormat);
+ long __stdcall CheckDeviceMultiSampleType(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT surfaceFormat, int windowed, D3DMULTISAMPLE_TYPE multiSampleType, unsigned long *qualityLevels);
+ long __stdcall CheckDepthStencilMatch(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT adapterFormat, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat);
+ long __stdcall CheckDeviceFormatConversion(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT sourceFormat, D3DFORMAT targetFormat);
+ long __stdcall GetDeviceCaps(unsigned int adapter, D3DDEVTYPE deviceType, D3DCAPS9 *caps);
+ HMONITOR __stdcall GetAdapterMonitor(unsigned int adapter);
+ long __stdcall CreateDevice(unsigned int adapter, D3DDEVTYPE deviceType, HWND focusWindow, unsigned long behaviorFlags, D3DPRESENT_PARAMETERS *presentParameters, IDirect3DDevice9 **returnedDeviceInterface);
+
+ protected:
+ // Creation parameters
+ const int version;
+ const HINSTANCE instance;
+
+ // Real D3D9 library
+ HMODULE d3d9Lib;
+
+ private:
+ void loadSystemD3D9();
+
+ DEVMODE *displayMode;
+ int numDisplayModes;
+ bool disableAlphaMode; // Disable A8R8G8B8 display mode support
+ bool disable10BitMode; // Disable A2R10G10B10 display mode support
+
+ //Real IDirect3D9 object
+ IDirect3D9 *d3d9;
+ };
+}
+
+#endif // D3D9_Direct3D9_hpp
diff --git a/src/D3D9/Direct3D9Ex.cpp b/src/D3D9/Direct3D9Ex.cpp
new file mode 100644
index 0000000..a651ef2
--- /dev/null
+++ b/src/D3D9/Direct3D9Ex.cpp
@@ -0,0 +1,379 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3D9Ex.hpp"
+
+#include "Direct3DDevice9Ex.hpp"
+#include "SwiftShader.hpp"
+#include "Debug.hpp"
+
+namespace sw
+{
+ extern bool postBlendSRGB;
+}
+
+namespace D3D9
+{
+ Direct3D9Ex::Direct3D9Ex(int version, const HINSTANCE instance) : Direct3D9(version, instance)
+ {
+ d3d9ex = 0;
+ }
+
+ Direct3D9Ex::~Direct3D9Ex()
+ {
+ }
+
+ long Direct3D9Ex::QueryInterface(const IID &iid, void **object)
+ {
+ TRACE("const IID &iid = 0x%0.8p, void **object = 0x%0.8p", iid, object);
+
+ if(iid == IID_IDirect3D9Ex ||
+ iid == IID_IDirect3D9 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+ else if(iid == IID_SwiftShaderPrivateV1)
+ {
+ SwiftShader *swiftShader = new SwiftShader(this);
+
+ *object = swiftShader;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long Direct3D9Ex::AddRef()
+ {
+ TRACE("void");
+
+ return Direct3D9::AddRef();
+ }
+
+ unsigned long Direct3D9Ex::Release()
+ {
+ TRACE("void");
+
+ return Direct3D9::Release();
+ }
+
+ long Direct3D9Ex::RegisterSoftwareDevice(void *initializeFunction)
+ {
+ TRACE("void *initializeFunction = 0x%0.8p", initializeFunction);
+
+ loadSystemD3D9ex();
+
+ if(d3d9ex)
+ {
+ return d3d9ex->RegisterSoftwareDevice(initializeFunction);
+ }
+ else
+ {
+ return INVALIDCALL();
+ }
+ }
+
+ unsigned int Direct3D9Ex::GetAdapterCount()
+ {
+ TRACE("void");
+
+ return Direct3D9::GetAdapterCount();
+ }
+
+ long Direct3D9Ex::GetAdapterIdentifier(unsigned int adapter, unsigned long flags, D3DADAPTER_IDENTIFIER9 *identifier)
+ {
+ TRACE("unsigned int adapter = %d, unsigned long flags = 0x%0.8X, D3DADAPTER_IDENTIFIER9 *identifier = 0x%0.8p", adapter, flags, identifier);
+
+ return Direct3D9::GetAdapterIdentifier(adapter, flags, identifier);
+ }
+
+ unsigned int Direct3D9Ex::GetAdapterModeCount(unsigned int adapter, D3DFORMAT format)
+ {
+ TRACE("unsigned int adapter = %d, D3DFORMAT format = %d", adapter, format);
+
+ return Direct3D9::GetAdapterModeCount(adapter, format);
+ }
+
+ long Direct3D9Ex::EnumAdapterModes(unsigned int adapter, D3DFORMAT format, unsigned int index, D3DDISPLAYMODE *mode)
+ {
+ TRACE("unsigned int adapter = %d, D3DFORMAT format = %d, unsigned int index = %d, D3DDISPLAYMODE *mode = 0x%0.8p", adapter, format, index, mode);
+
+ return Direct3D9::EnumAdapterModes(adapter, format, index, mode);
+ }
+
+ long Direct3D9Ex::GetAdapterDisplayMode(unsigned int adapter, D3DDISPLAYMODE *mode)
+ {
+ TRACE("unsigned int adapter = %d, D3DDISPLAYMODE *mode = 0x%0.8p", adapter, mode);
+
+ return Direct3D9::GetAdapterDisplayMode(adapter, mode);
+ }
+
+ long Direct3D9Ex::CheckDeviceType(unsigned int adapter, D3DDEVTYPE checkType, D3DFORMAT displayFormat, D3DFORMAT backBufferFormat, int windowed)
+ {
+ TRACE("unsigned int adapter = %d, D3DDEVTYPE checkType = %d, D3DFORMAT displayFormat = %d, D3DFORMAT backBufferFormat = %d, int windowed = %d", adapter, checkType, displayFormat, backBufferFormat, windowed);
+
+ if(checkType != D3DDEVTYPE_HAL)
+ {
+ loadSystemD3D9ex();
+
+ if(d3d9ex)
+ {
+ return d3d9ex->CheckDeviceType(adapter, checkType, displayFormat, backBufferFormat, windowed);
+ }
+ else
+ {
+ return CheckDeviceType(adapter, D3DDEVTYPE_HAL, displayFormat, backBufferFormat, windowed);
+ }
+ }
+
+ return Direct3D9::CheckDeviceType(adapter, checkType, displayFormat, backBufferFormat, windowed);
+ }
+
+ long Direct3D9Ex::CheckDeviceFormat(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT adapterFormat, unsigned long usage, D3DRESOURCETYPE resourceType, D3DFORMAT checkFormat)
+ {
+ TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DFORMAT adapterFormat = %d, unsigned long usage = %d, D3DRESOURCETYPE resourceType = %d, D3DFORMAT checkFormat = %d", adapter, deviceType, adapterFormat, usage, resourceType, checkFormat);
+
+ if(deviceType != D3DDEVTYPE_HAL)
+ {
+ loadSystemD3D9ex();
+
+ if(d3d9ex)
+ {
+ return d3d9ex->CheckDeviceFormat(adapter, deviceType, adapterFormat, usage, resourceType, checkFormat);
+ }
+ else
+ {
+ return CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, adapterFormat, usage, resourceType, checkFormat);
+ }
+ }
+
+ return Direct3D9::CheckDeviceFormat(adapter, deviceType, adapterFormat, usage, resourceType, checkFormat);
+ }
+
+ long Direct3D9Ex::CheckDeviceMultiSampleType(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT surfaceFormat, int windowed, D3DMULTISAMPLE_TYPE multiSampleType, unsigned long *qualityLevels)
+ {
+ TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DFORMAT surfaceFormat = %d, int windowed = %d, D3DMULTISAMPLE_TYPE multiSampleType = %d, unsigned long *qualityLevels = 0x%0.8p", adapter, deviceType, surfaceFormat, windowed, multiSampleType, qualityLevels);
+
+ if(deviceType != D3DDEVTYPE_HAL)
+ {
+ loadSystemD3D9ex();
+
+ if(d3d9ex)
+ {
+ return d3d9ex->CheckDeviceMultiSampleType(adapter, deviceType, surfaceFormat, windowed, multiSampleType, qualityLevels);
+ }
+ else
+ {
+ return CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, surfaceFormat, windowed, multiSampleType, qualityLevels);
+ }
+ }
+
+ return Direct3D9::CheckDeviceMultiSampleType(adapter, deviceType, surfaceFormat, windowed, multiSampleType, qualityLevels);
+ }
+
+ long Direct3D9Ex::CheckDepthStencilMatch(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT adapterFormat, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat)
+ {
+ TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DFORMAT adapterFormat = %d, D3DFORMAT renderTargetFormat = %d, D3DFORMAT depthStencilFormat = %d", adapter, deviceType, adapterFormat, renderTargetFormat, depthStencilFormat);
+
+ return Direct3D9::CheckDepthStencilMatch(adapter, deviceType, adapterFormat, renderTargetFormat, depthStencilFormat);
+ }
+
+ long Direct3D9Ex::CheckDeviceFormatConversion(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT sourceFormat, D3DFORMAT targetFormat)
+ {
+ TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DFORMAT sourceFormat = %d, D3DFORMAT targetFormat = %d", adapter, deviceType, sourceFormat, targetFormat);
+
+ if(deviceType != D3DDEVTYPE_HAL)
+ {
+ loadSystemD3D9ex();
+
+ if(d3d9ex)
+ {
+ return d3d9ex->CheckDeviceFormatConversion(adapter, deviceType, sourceFormat, targetFormat);
+ }
+ else
+ {
+ return CheckDeviceFormatConversion(adapter, D3DDEVTYPE_HAL, sourceFormat, targetFormat);
+ }
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3D9Ex::GetDeviceCaps(unsigned int adapter, D3DDEVTYPE deviceType, D3DCAPS9 *capabilities)
+ {
+ TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DCAPS9 *capabilities = 0x%0.8p", adapter, deviceType, capabilities);
+
+ if(deviceType != D3DDEVTYPE_HAL)
+ {
+ loadSystemD3D9ex();
+
+ if(d3d9ex)
+ {
+ return d3d9ex->GetDeviceCaps(adapter, deviceType, capabilities);
+ }
+ else
+ {
+ return GetDeviceCaps(adapter, D3DDEVTYPE_HAL, capabilities);
+ }
+ }
+
+ long result = Direct3D9::GetDeviceCaps(adapter, deviceType, capabilities);
+
+ if(sw::postBlendSRGB)
+ {
+ capabilities->PrimitiveMiscCaps |= D3DPMISCCAPS_POSTBLENDSRGBCONVERT; // Indicates device can perform conversion to sRGB after blending.
+ }
+
+ return result;
+ }
+
+ HMONITOR Direct3D9Ex::GetAdapterMonitor(unsigned int adapter)
+ {
+ TRACE("unsigned int adapter = %d", adapter);
+
+ return Direct3D9::GetAdapterMonitor(adapter);
+ }
+
+ long Direct3D9Ex::CreateDevice(unsigned int adapter, D3DDEVTYPE deviceType, HWND focusWindow, unsigned long behaviorFlags, D3DPRESENT_PARAMETERS *presentParameters, IDirect3DDevice9 **returnedDeviceInterface)
+ {
+ TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, HWND focusWindow = %d, unsigned long behaviorFlags = 0x%0.8X, D3DPRESENT_PARAMETERS *presentParameters = 0x%0.8p, IDirect3DDevice9 **returnedDeviceInterface = 0x%0.8p", adapter, deviceType, focusWindow, behaviorFlags, presentParameters, returnedDeviceInterface);
+
+ if(!focusWindow || !presentParameters || !returnedDeviceInterface)
+ {
+ *returnedDeviceInterface = 0;
+
+ return INVALIDCALL();
+ }
+
+ D3DDISPLAYMODEEX fullscreenDisplayMode = {0};
+ fullscreenDisplayMode.Size = sizeof(D3DDISPLAYMODEEX);
+ fullscreenDisplayMode.Format = presentParameters->BackBufferFormat;
+ fullscreenDisplayMode.Width = presentParameters->BackBufferWidth;
+ fullscreenDisplayMode.Height = presentParameters->BackBufferHeight;
+ fullscreenDisplayMode.RefreshRate = presentParameters->FullScreen_RefreshRateInHz;
+ fullscreenDisplayMode.ScanLineOrdering = D3DSCANLINEORDERING_PROGRESSIVE;
+
+ return CreateDeviceEx(adapter, deviceType, focusWindow, behaviorFlags, presentParameters, presentParameters->Windowed ? 0 : &fullscreenDisplayMode, (IDirect3DDevice9Ex**)returnedDeviceInterface);
+ }
+
+ unsigned int __stdcall Direct3D9Ex::GetAdapterModeCountEx(unsigned int adapter, const D3DDISPLAYMODEFILTER *filter)
+ {
+ TRACE("unsigned int adapter = %d, const D3DDISPLAYMODEFILTER *filter = 0x%0.8p", adapter, filter);
+
+ return Direct3D9::GetAdapterModeCount(adapter, filter->Format); // FIXME
+ }
+
+ long __stdcall Direct3D9Ex::EnumAdapterModesEx(unsigned int adapter, const D3DDISPLAYMODEFILTER *filter, unsigned int index, D3DDISPLAYMODEEX *modeEx)
+ {
+ TRACE("unsigned int adapter = %d, const D3DDISPLAYMODEFILTER *filter = 0x%0.8p, unsigned int index = %d, D3DDISPLAYMODEEX *modeEx = 0x%0.8p", adapter, filter, index, modeEx);
+
+ D3DDISPLAYMODE mode;
+
+ mode.Format = modeEx->Format;
+ mode.Width = modeEx->Width;
+ mode.Height = modeEx->Height;
+ mode.RefreshRate = modeEx->RefreshRate;
+
+ return Direct3D9::EnumAdapterModes(adapter, filter->Format, index, &mode); // FIXME
+ }
+
+ long __stdcall Direct3D9Ex::GetAdapterDisplayModeEx(unsigned int adapter, D3DDISPLAYMODEEX *modeEx, D3DDISPLAYROTATION *rotation)
+ {
+ TRACE("unsigned int adapter = %d, D3DDISPLAYMODEEX *modeEx = 0x%0.8p, D3DDISPLAYROTATION *rotation = 0x%0.8p", adapter, modeEx, rotation);
+
+ D3DDISPLAYMODE mode;
+
+ mode.Format = modeEx->Format;
+ mode.Width = modeEx->Width;
+ mode.Height = modeEx->Height;
+ mode.RefreshRate = modeEx->RefreshRate;
+
+ return GetAdapterDisplayMode(adapter, &mode); // FIXME
+ }
+
+ long __stdcall Direct3D9Ex::CreateDeviceEx(unsigned int adapter, D3DDEVTYPE deviceType, HWND focusWindow, DWORD behaviorFlags, D3DPRESENT_PARAMETERS *presentParameters, D3DDISPLAYMODEEX *fullscreenDisplayMode, IDirect3DDevice9Ex **returnedDeviceInterface)
+ {
+ TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, HWND focusWindow = %d, DWORD behaviorFlags = 0x%0.8X, D3DPRESENT_PARAMETERS *presentParameters = 0x%0.8p, D3DDISPLAYMODEEX *fullscreenDisplayMode = 0x%0.8p, IDirect3DDevice9Ex **returnedDeviceInterface = 0x%0.8p", adapter, deviceType, focusWindow, behaviorFlags, presentParameters, fullscreenDisplayMode, returnedDeviceInterface);
+
+ if(deviceType != D3DDEVTYPE_HAL)
+ {
+ loadSystemD3D9ex();
+
+ if(d3d9ex)
+ {
+ return d3d9ex->CreateDeviceEx(adapter, deviceType, focusWindow, behaviorFlags, presentParameters, fullscreenDisplayMode, returnedDeviceInterface);
+ }
+ else
+ {
+ CreateDeviceEx(adapter, deviceType, focusWindow, behaviorFlags, presentParameters, fullscreenDisplayMode, returnedDeviceInterface);
+ }
+ }
+
+ if(!focusWindow || !presentParameters || !returnedDeviceInterface)
+ {
+ *returnedDeviceInterface = 0;
+
+ return INVALIDCALL();
+ }
+
+ *returnedDeviceInterface = new Direct3DDevice9Ex(instance, this, adapter, deviceType, focusWindow, behaviorFlags, presentParameters);
+
+ if(*returnedDeviceInterface)
+ {
+ (*returnedDeviceInterface)->AddRef();
+ }
+
+ return D3D_OK;
+ }
+
+ long __stdcall Direct3D9Ex::GetAdapterLUID(unsigned int adapter, LUID *luid)
+ {
+ TRACE("unsigned int adapter = %d, LUID *luid = 0x%0.8p", adapter, luid);
+
+ if(adapter != D3DADAPTER_DEFAULT)
+ {
+ UNIMPLEMENTED();
+ }
+
+ // FIXME: Should return a presistent id using AllocateLocallyUniqueId()
+ luid->LowPart = 0x0000001;
+ luid->HighPart = 0x0000000;
+
+ return D3D_OK;
+ }
+
+ void Direct3D9Ex::loadSystemD3D9ex()
+ {
+ if(d3d9ex)
+ {
+ return;
+ }
+
+ char d3d9Path[MAX_PATH + 16];
+ GetSystemDirectory(d3d9Path, MAX_PATH);
+ strcat(d3d9Path, "\\d3d9.dll");
+ d3d9Lib = LoadLibrary(d3d9Path);
+
+ if(d3d9Lib)
+ {
+ typedef IDirect3D9Ex* (__stdcall *DIRECT3DCREATE9EX)(unsigned int, IDirect3D9Ex**);
+ DIRECT3DCREATE9EX direct3DCreate9Ex = (DIRECT3DCREATE9EX)GetProcAddress(d3d9Lib, "Direct3DCreate9Ex");
+ direct3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
+ }
+ }
+}
diff --git a/src/D3D9/Direct3D9Ex.hpp b/src/D3D9/Direct3D9Ex.hpp
new file mode 100644
index 0000000..9e1e319
--- /dev/null
+++ b/src/D3D9/Direct3D9Ex.hpp
@@ -0,0 +1,67 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Direct3D9Ex_hpp
+#define D3D9_Direct3D9Ex_hpp
+
+#include "Direct3D9.hpp"
+
+//#include <stdio.h>
+#include <d3d9.h>
+
+namespace D3D9
+{
+ class Direct3DDevice9;
+
+ class Direct3D9Ex : public IDirect3D9Ex, public Direct3D9
+ {
+ public:
+ Direct3D9Ex(int version, const HINSTANCE instance);
+
+ virtual ~Direct3D9Ex();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // IDirect3D9 methods
+ long __stdcall RegisterSoftwareDevice(void *initializeFunction);
+ unsigned int __stdcall GetAdapterCount();
+ long __stdcall GetAdapterIdentifier(unsigned int adapter, unsigned long flags, D3DADAPTER_IDENTIFIER9 *identifier);
+ unsigned int __stdcall GetAdapterModeCount(unsigned int adapter, D3DFORMAT format);
+ long __stdcall EnumAdapterModes(unsigned int adapter, D3DFORMAT format, unsigned int index, D3DDISPLAYMODE *mode);
+ long __stdcall GetAdapterDisplayMode(unsigned int adapter, D3DDISPLAYMODE *mode);
+ long __stdcall CheckDeviceType(unsigned int adapter, D3DDEVTYPE checkType, D3DFORMAT displayFormat, D3DFORMAT backBufferFormat, int windowed);
+ long __stdcall CheckDeviceFormat(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT adapterFormat, unsigned long usage, D3DRESOURCETYPE type, D3DFORMAT checkFormat);
+ long __stdcall CheckDeviceMultiSampleType(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT surfaceFormat, int windowed, D3DMULTISAMPLE_TYPE multiSampleType, unsigned long *qualityLevels);
+ long __stdcall CheckDepthStencilMatch(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT adapterFormat, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat);
+ long __stdcall CheckDeviceFormatConversion(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT sourceFormat, D3DFORMAT targetFormat);
+ long __stdcall GetDeviceCaps(unsigned int adapter, D3DDEVTYPE deviceType, D3DCAPS9 *caps);
+ HMONITOR __stdcall GetAdapterMonitor(unsigned int adapter);
+ long __stdcall CreateDevice(unsigned int adapter, D3DDEVTYPE deviceType, HWND focusWindow, unsigned long behaviorFlags, D3DPRESENT_PARAMETERS *presentParameters, IDirect3DDevice9 **returnedDeviceInterface);
+
+ // IDirect3D9Ex methods
+ unsigned int __stdcall GetAdapterModeCountEx(unsigned int adapter, const D3DDISPLAYMODEFILTER *filter);
+ long __stdcall EnumAdapterModesEx(unsigned int adapter, const D3DDISPLAYMODEFILTER *filter, unsigned int index, D3DDISPLAYMODEEX *mode);
+ long __stdcall GetAdapterDisplayModeEx(unsigned int adapter, D3DDISPLAYMODEEX *mode, D3DDISPLAYROTATION *rotation);
+ long __stdcall CreateDeviceEx(unsigned int adapter, D3DDEVTYPE deviceType, HWND focusWindow, DWORD behaviorFlags, D3DPRESENT_PARAMETERS *presentParameters, D3DDISPLAYMODEEX *fullscreenDisplayMode, IDirect3DDevice9Ex **returnedDeviceInterface);
+ long __stdcall GetAdapterLUID(unsigned int adapter, LUID *luid);
+
+ private:
+ void loadSystemD3D9ex();
+
+ // Real IDirect3D9Ex object
+ IDirect3D9Ex *d3d9ex;
+ };
+}
+
+#endif // D3D9_Direct3D9Ex_hpp
diff --git a/src/D3D9/Direct3DBaseTexture9.cpp b/src/D3D9/Direct3DBaseTexture9.cpp
new file mode 100644
index 0000000..0ab979b
--- /dev/null
+++ b/src/D3D9/Direct3DBaseTexture9.cpp
@@ -0,0 +1,252 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3DBaseTexture9.hpp"
+
+#include "Direct3DDevice9.hpp"
+#include "Resource.hpp"
+#include "Debug.hpp"
+
+#include <assert.h>
+
+namespace D3D9
+{
+ Direct3DBaseTexture9::Direct3DBaseTexture9(Direct3DDevice9 *device, D3DRESOURCETYPE type, D3DFORMAT format, D3DPOOL pool, unsigned long levels, unsigned long usage) : Direct3DResource9(device, type, pool, 0), format(format), levels(levels), usage(usage)
+ {
+ filterType = D3DTEXF_LINEAR;
+ LOD = 0;
+
+ resource = new sw::Resource(0);
+ }
+
+ Direct3DBaseTexture9::~Direct3DBaseTexture9()
+ {
+ resource->destruct();
+ }
+
+ long Direct3DBaseTexture9::QueryInterface(const IID &iid, void **object)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(iid == IID_IDirect3DBaseTexture9 ||
+ iid == IID_IDirect3DResource9 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long Direct3DBaseTexture9::AddRef()
+ {
+ TRACE("");
+
+ return Direct3DResource9::AddRef();
+ }
+
+ unsigned long Direct3DBaseTexture9::Release()
+ {
+ TRACE("");
+
+ return Direct3DResource9::Release();
+ }
+
+ long Direct3DBaseTexture9::FreePrivateData(const GUID &guid)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::FreePrivateData(guid);
+ }
+
+ long Direct3DBaseTexture9::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::GetPrivateData(guid, data, size);
+ }
+
+ void Direct3DBaseTexture9::PreLoad()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ Direct3DResource9::PreLoad();
+ }
+
+ long Direct3DBaseTexture9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::SetPrivateData(guid, data, size, flags);
+ }
+
+ long Direct3DBaseTexture9::GetDevice(IDirect3DDevice9 **device)
+ {
+ CriticalSection cs(this->device);
+
+ TRACE("");
+
+ return Direct3DResource9::GetDevice(device);
+ }
+
+ unsigned long Direct3DBaseTexture9::SetPriority(unsigned long newPriority)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::SetPriority(newPriority);
+ }
+
+ unsigned long Direct3DBaseTexture9::GetPriority()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::GetPriority();
+ }
+
+ D3DRESOURCETYPE Direct3DBaseTexture9::GetType()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::GetType();
+ }
+
+ D3DTEXTUREFILTERTYPE Direct3DBaseTexture9::GetAutoGenFilterType()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(usage & D3DUSAGE_AUTOGENMIPMAP)
+ {
+ return filterType;
+ }
+ else
+ {
+ return D3DTEXF_NONE;
+ }
+ }
+
+ unsigned long Direct3DBaseTexture9::GetLevelCount()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(usage & D3DUSAGE_AUTOGENMIPMAP)
+ {
+ return 1;
+ }
+
+ return levels;
+ }
+
+ unsigned long Direct3DBaseTexture9::GetLOD()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(pool & D3DPOOL_MANAGED)
+ {
+ return LOD;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ long Direct3DBaseTexture9::SetAutoGenFilterType(D3DTEXTUREFILTERTYPE filterType)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(usage & D3DUSAGE_AUTOGENMIPMAP)
+ {
+ this->filterType = filterType; // FIXME: Check if valid
+ // FIXME: Dirty the mipmap chain
+
+ return D3D_OK;
+ }
+ else
+ {
+ return D3DTEXF_NONE;
+ }
+ }
+
+ unsigned long Direct3DBaseTexture9::SetLOD(unsigned long newLOD)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ unsigned long oldLOD = LOD;
+ LOD = newLOD < levels ? newLOD : levels - 1;
+
+ if(pool & D3DPOOL_MANAGED)
+ {
+ return oldLOD;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ void Direct3DBaseTexture9::GenerateMipSubLevels()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+ }
+
+ sw::Resource *Direct3DBaseTexture9::getResource() const
+ {
+ return resource;
+ }
+
+ unsigned long Direct3DBaseTexture9::getInternalLevelCount() const
+ {
+ return levels;
+ }
+
+ unsigned long Direct3DBaseTexture9::getUsage() const
+ {
+ return usage;
+ }
+
+ D3DFORMAT Direct3DBaseTexture9::getFormat() const
+ {
+ return format;
+ }
+}
diff --git a/src/D3D9/Direct3DBaseTexture9.hpp b/src/D3D9/Direct3DBaseTexture9.hpp
new file mode 100644
index 0000000..ed785fe
--- /dev/null
+++ b/src/D3D9/Direct3DBaseTexture9.hpp
@@ -0,0 +1,76 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Direct3DBaseTexture9_hpp
+#define D3D9_Direct3DBaseTexture9_hpp
+
+#include "Direct3DResource9.hpp"
+
+#include <d3d9.h>
+
+namespace sw
+{
+ class Resource;
+}
+
+namespace D3D9
+{
+ class Direct3DBaseTexture9 : public IDirect3DBaseTexture9, public Direct3DResource9
+ {
+ public:
+ Direct3DBaseTexture9(Direct3DDevice9 *device, D3DRESOURCETYPE type, D3DFORMAT format, D3DPOOL pool, unsigned long levels, unsigned long usage);
+
+ virtual ~Direct3DBaseTexture9();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // IDirect3DResource9 methods
+ long __stdcall GetDevice(IDirect3DDevice9 **device);
+ long __stdcall SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags);
+ long __stdcall GetPrivateData(const GUID &guid, void *data, unsigned long *size);
+ long __stdcall FreePrivateData(const GUID &guid);
+ unsigned long __stdcall SetPriority(unsigned long newPriority);
+ unsigned long __stdcall GetPriority();
+ void __stdcall PreLoad();
+ D3DRESOURCETYPE __stdcall GetType();
+
+ // IDirect3DBaseTexture9 methods
+ unsigned long __stdcall SetLOD(unsigned long newLOD);
+ unsigned long __stdcall GetLOD();
+ unsigned long __stdcall GetLevelCount();
+ long __stdcall SetAutoGenFilterType(D3DTEXTUREFILTERTYPE filterType);
+ D3DTEXTUREFILTERTYPE __stdcall GetAutoGenFilterType();
+ void __stdcall GenerateMipSubLevels();
+
+ // Intenal methods
+ sw::Resource *getResource() const;
+ unsigned long getInternalLevelCount() const;
+ unsigned long getUsage() const;
+ D3DFORMAT getFormat() const;
+
+ protected:
+ // Creation parameters
+ unsigned long levels; // Recalculated when 0
+ const unsigned long usage;
+ const D3DFORMAT format;
+
+ sw::Resource *resource;
+
+ private:
+ D3DTEXTUREFILTERTYPE filterType;
+ unsigned long LOD;
+ };
+}
+
+#endif // D3D9_Direct3DBaseTexture9_hpp
diff --git a/src/D3D9/Direct3DCubeTexture9.cpp b/src/D3D9/Direct3DCubeTexture9.cpp
new file mode 100644
index 0000000..992095e
--- /dev/null
+++ b/src/D3D9/Direct3DCubeTexture9.cpp
@@ -0,0 +1,332 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3DCubeTexture9.hpp"
+
+#include "Direct3DDevice9.hpp"
+#include "Direct3DSurface9.hpp"
+#include "Resource.hpp"
+#include "Debug.hpp"
+
+#include <assert.h>
+
+namespace D3D9
+{
+ Direct3DCubeTexture9::Direct3DCubeTexture9(Direct3DDevice9 *device, unsigned int edgeLength, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool) : Direct3DBaseTexture9(device, D3DRTYPE_CUBETEXTURE, format, pool, levels, usage), edgeLength(edgeLength)
+ {
+ if(levels == 0)
+ {
+ this->levels = sw::log2(sw::max((int)edgeLength, 1)) + 1;
+ }
+
+ for(unsigned int face = 0; face < 6; face++)
+ {
+ int width = edgeLength;
+ int height = edgeLength;
+
+ for(unsigned int level = 0; level < MIPMAP_LEVELS; level++)
+ {
+ if(level < this->levels)
+ {
+ surfaceLevel[face][level] = new Direct3DSurface9(device, this, width, height, format, pool, D3DMULTISAMPLE_NONE, 0, false, usage);
+ surfaceLevel[face][level]->bind();
+ }
+ else
+ {
+ surfaceLevel[face][level] = 0;
+ }
+
+ width = sw::max(1, width / 2);
+ height = sw::max(1, height / 2);
+ }
+ }
+ }
+
+ Direct3DCubeTexture9::~Direct3DCubeTexture9()
+ {
+ resource->lock(sw::DESTRUCT);
+
+ for(unsigned int face = 0; face < 6; face++)
+ {
+ for(int level = 0; level < MIPMAP_LEVELS; level++)
+ {
+ if(surfaceLevel[face][level])
+ {
+ surfaceLevel[face][level]->unbind();
+ surfaceLevel[face][level] = 0;
+ }
+ }
+ }
+
+ resource->unlock();
+ }
+
+ long Direct3DCubeTexture9::QueryInterface(const IID &iid, void **object)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(iid == IID_IDirect3DCubeTexture9 ||
+ iid == IID_IDirect3DBaseTexture9 ||
+ iid == IID_IDirect3DResource9 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long Direct3DCubeTexture9::AddRef()
+ {
+ TRACE("");
+
+ return Direct3DBaseTexture9::AddRef();
+ }
+
+ unsigned long Direct3DCubeTexture9::Release()
+ {
+ TRACE("");
+
+ return Direct3DBaseTexture9::Release();
+ }
+
+ long Direct3DCubeTexture9::FreePrivateData(const GUID &guid)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::FreePrivateData(guid);
+ }
+
+ long Direct3DCubeTexture9::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetPrivateData(guid, data, size);
+ }
+
+ void Direct3DCubeTexture9::PreLoad()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ Direct3DBaseTexture9::PreLoad();
+ }
+
+ long Direct3DCubeTexture9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::SetPrivateData(guid, data, size, flags);
+ }
+
+ long Direct3DCubeTexture9::GetDevice(IDirect3DDevice9 **device)
+ {
+ CriticalSection cs(this->device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetDevice(device);
+ }
+
+ unsigned long Direct3DCubeTexture9::SetPriority(unsigned long newPriority)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::SetPriority(newPriority);
+ }
+
+ unsigned long Direct3DCubeTexture9::GetPriority()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetPriority();
+ }
+
+ D3DRESOURCETYPE Direct3DCubeTexture9::GetType()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetType();
+ }
+
+ void Direct3DCubeTexture9::GenerateMipSubLevels()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!(usage & D3DUSAGE_AUTOGENMIPMAP))
+ {
+ return;
+ }
+
+ resource->lock(sw::PUBLIC);
+
+ for(unsigned int face = 0; face < 6; face++)
+ {
+ if(!surfaceLevel[face][0]->hasDirtyMipmaps())
+ {
+ continue;
+ }
+
+ for(unsigned int i = 0; i < levels - 1; i++)
+ {
+ device->stretchRect(surfaceLevel[face][i], 0, surfaceLevel[face][i + 1], 0, GetAutoGenFilterType());
+ }
+
+ surfaceLevel[face][0]->cleanMipmaps();
+ }
+
+ resource->unlock();
+ }
+
+ D3DTEXTUREFILTERTYPE Direct3DCubeTexture9::GetAutoGenFilterType()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetAutoGenFilterType();
+ }
+
+ unsigned long Direct3DCubeTexture9::GetLevelCount()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetLevelCount();
+ }
+
+ unsigned long Direct3DCubeTexture9::GetLOD()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetLOD();
+ }
+
+ long Direct3DCubeTexture9::SetAutoGenFilterType(D3DTEXTUREFILTERTYPE filterType)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::SetAutoGenFilterType(filterType);
+ }
+
+ unsigned long Direct3DCubeTexture9::SetLOD(unsigned long newLOD)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::SetLOD(newLOD);
+ }
+
+ long Direct3DCubeTexture9::AddDirtyRect(D3DCUBEMAP_FACES face, const RECT *dirtyRect)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ // UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ long Direct3DCubeTexture9::GetCubeMapSurface(D3DCUBEMAP_FACES face, unsigned int level, IDirect3DSurface9 **cubeMapSurface)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ *cubeMapSurface = 0;
+
+ if(face >= 6 || level >= GetLevelCount() || !surfaceLevel[face][level])
+ {
+ return INVALIDCALL();
+ }
+
+ surfaceLevel[face][level]->AddRef();
+ *cubeMapSurface = surfaceLevel[face][level];
+
+ return D3D_OK;
+ }
+
+ long Direct3DCubeTexture9::GetLevelDesc(unsigned int level, D3DSURFACE_DESC *description)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!description || level >= GetLevelCount() || !surfaceLevel[0][level])
+ {
+ return INVALIDCALL();
+ }
+
+ return surfaceLevel[0][level]->GetDesc(description);
+ }
+
+ long Direct3DCubeTexture9::LockRect(D3DCUBEMAP_FACES face, unsigned int level, D3DLOCKED_RECT *lockedRect, const RECT *rect, unsigned long flags)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!lockedRect || face >= 6 || level >= GetLevelCount() || !surfaceLevel[face][level])
+ {
+ return INVALIDCALL();
+ }
+
+ return surfaceLevel[face][level]->LockRect(lockedRect, rect, flags);
+ }
+
+ long Direct3DCubeTexture9::UnlockRect(D3DCUBEMAP_FACES face, unsigned int level)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(face >= 6 || level >= GetLevelCount() || !surfaceLevel[face][level])
+ {
+ return INVALIDCALL();
+ }
+
+ return surfaceLevel[face][level]->UnlockRect();
+ }
+
+ Direct3DSurface9 *Direct3DCubeTexture9::getInternalCubeMapSurface(D3DCUBEMAP_FACES face, unsigned int level)
+ {
+ return surfaceLevel[face][level];
+ }
+}
\ No newline at end of file
diff --git a/src/D3D9/Direct3DCubeTexture9.hpp b/src/D3D9/Direct3DCubeTexture9.hpp
new file mode 100644
index 0000000..bead8ec
--- /dev/null
+++ b/src/D3D9/Direct3DCubeTexture9.hpp
@@ -0,0 +1,73 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Direct3DCubeTexture9_hpp
+#define D3D9_Direct3DCubeTexture9_hpp
+
+#include "Direct3DBaseTexture9.hpp"
+
+#include "Config.hpp"
+
+#include <d3d9.h>
+
+namespace D3D9
+{
+ class Direct3DSurface9;
+
+ class Direct3DCubeTexture9 : public IDirect3DCubeTexture9, public Direct3DBaseTexture9
+ {
+ public:
+ Direct3DCubeTexture9(Direct3DDevice9 *device, unsigned int edgeLength, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool);
+
+ virtual ~Direct3DCubeTexture9();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // IDirect3DResource9 methods
+ long __stdcall GetDevice(IDirect3DDevice9 **device);
+ long __stdcall SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags);
+ long __stdcall GetPrivateData(const GUID &guid, void *data, unsigned long *size);
+ long __stdcall FreePrivateData(const GUID &guid);
+ unsigned long __stdcall SetPriority(unsigned long newPriority);
+ unsigned long __stdcall GetPriority();
+ void __stdcall PreLoad();
+ D3DRESOURCETYPE __stdcall GetType();
+
+ // IDirect3DBaseTexture9 methods
+ unsigned long __stdcall SetLOD(unsigned long newLOD);
+ unsigned long __stdcall GetLOD();
+ unsigned long __stdcall GetLevelCount();
+ long __stdcall SetAutoGenFilterType(D3DTEXTUREFILTERTYPE filterType);
+ D3DTEXTUREFILTERTYPE __stdcall GetAutoGenFilterType();
+ void __stdcall GenerateMipSubLevels();
+
+ // IDirect3DCubeTexture9 methods
+ long __stdcall GetLevelDesc(unsigned int level, D3DSURFACE_DESC *description);
+ long __stdcall GetCubeMapSurface(D3DCUBEMAP_FACES face, unsigned int level, IDirect3DSurface9 **cubeMapSurface);
+ long __stdcall LockRect(D3DCUBEMAP_FACES face, unsigned int level, D3DLOCKED_RECT *lockedRect, const RECT *rect, unsigned long flags);
+ long __stdcall UnlockRect(D3DCUBEMAP_FACES face, unsigned int level);
+ long __stdcall AddDirtyRect(D3DCUBEMAP_FACES face, const RECT *dirtyRect);
+
+ // Internal methods
+ Direct3DSurface9 *getInternalCubeMapSurface(D3DCUBEMAP_FACES face, unsigned int level);
+
+ private:
+ // Creation parameters
+ const unsigned int edgeLength;
+
+ Direct3DSurface9 *surfaceLevel[6][MIPMAP_LEVELS];
+ };
+}
+
+#endif // D3D9_Direct3D9_hpp
diff --git a/src/D3D9/Direct3DDevice9.cpp b/src/D3D9/Direct3DDevice9.cpp
new file mode 100644
index 0000000..f26724b
--- /dev/null
+++ b/src/D3D9/Direct3DDevice9.cpp
@@ -0,0 +1,6472 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3DDevice9.hpp"
+
+#include "Direct3D9.hpp"
+#include "Direct3DSurface9.hpp"
+#include "Direct3DIndexBuffer9.hpp"
+#include "Direct3DVertexBuffer9.hpp"
+#include "Direct3DTexture9.hpp"
+#include "Direct3DVolumeTexture9.hpp"
+#include "Direct3DCubeTexture9.hpp"
+#include "Direct3DVertexDeclaration9.hpp"
+#include "Direct3DSwapChain9.hpp"
+#include "Direct3DPixelShader9.hpp"
+#include "Direct3DVertexShader9.hpp"
+#include "Direct3DStateBlock9.hpp"
+#include "Direct3DQuery9.hpp"
+#include "Direct3DVolume9.hpp"
+
+#include "Debug.hpp"
+#include "Capabilities.hpp"
+#include "Math.hpp"
+#include "Renderer.hpp"
+#include "Config.hpp"
+#include "FrameBuffer.hpp"
+#include "Clipper.hpp"
+#include "Configurator.hpp"
+#include "Timer.hpp"
+#include "Resource.hpp"
+
+#include <assert.h>
+
+bool localShaderConstants = true;
+
+namespace D3D9
+{
+ inline unsigned long FtoDW(float f)
+ {
+ return (unsigned long&)f;
+ }
+
+ Direct3DDevice9::Direct3DDevice9(const HINSTANCE instance, Direct3D9 *d3d9, unsigned int adapter, D3DDEVTYPE deviceType, HWND focusWindow, unsigned long behaviourFlags, D3DPRESENT_PARAMETERS *presentParameters) : instance(instance), adapter(adapter), d3d9(d3d9), deviceType(deviceType), focusWindow(focusWindow), behaviourFlags(behaviourFlags)
+ {
+ InitializeCriticalSection(&criticalSection);
+
+ init = true;
+ stateRecorder = 0;
+
+ d3d9->AddRef();
+
+ context = new sw::Context();
+ renderer = new sw::Renderer(context);
+
+ swapChain = 0;
+ depthStencil = 0;
+ autoDepthStencil = 0;
+ renderTarget[0] = 0;
+ renderTarget[1] = 0;
+ renderTarget[2] = 0;
+ renderTarget[3] = 0;
+
+ for(int i = 0; i < 16 + 4; i++)
+ {
+ texture[i] = 0;
+ }
+
+ cursor = 0;
+
+ Reset(presentParameters);
+
+ pixelShader = 0;
+ vertexShader = 0;
+
+ lightsDirty = true;
+ pixelShaderDirty = true;
+ pixelShaderConstantsBDirty = 0;
+ pixelShaderConstantsFDirty = 0;
+ pixelShaderConstantsIDirty = 0;
+ vertexShaderDirty = true;
+ vertexShaderConstantsBDirty = 0;
+ vertexShaderConstantsFDirty = 0;
+ vertexShaderConstantsIDirty = 0;
+
+ for(int i = 0; i < 16; i++)
+ {
+ dataStream[i] = 0;
+ streamStride[i] = 0;
+ streamOffset[i] = 0;
+
+ streamSourceFreq[i] = 1;
+ }
+
+ indexData = 0;
+ vertexDeclaration = 0;
+
+ D3DMATERIAL9 material;
+
+ material.Diffuse.r = 1.0f;
+ material.Diffuse.g = 1.0f;
+ material.Diffuse.b = 1.0f;
+ material.Diffuse.a = 0.0f;
+ material.Ambient.r = 0.0f;
+ material.Ambient.g = 0.0f;
+ material.Ambient.b = 0.0f;
+ material.Ambient.a = 0.0f;
+ material.Emissive.r = 0.0f;
+ material.Emissive.g = 0.0f;
+ material.Emissive.b = 0.0f;
+ material.Emissive.a = 0.0f;
+ material.Specular.r = 0.0f;
+ material.Specular.g = 0.0f;
+ material.Specular.b = 0.0f;
+ material.Specular.a = 0.0f;
+ material.Power = 0.0f;
+
+ SetMaterial(&material);
+
+ D3DMATRIX identity = {1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1};
+
+ SetTransform(D3DTS_VIEW, &identity);
+ SetTransform(D3DTS_PROJECTION, &identity);
+ SetTransform(D3DTS_TEXTURE0, &identity);
+ SetTransform(D3DTS_TEXTURE1, &identity);
+ SetTransform(D3DTS_TEXTURE2, &identity);
+ SetTransform(D3DTS_TEXTURE3, &identity);
+ SetTransform(D3DTS_TEXTURE4, &identity);
+ SetTransform(D3DTS_TEXTURE5, &identity);
+ SetTransform(D3DTS_TEXTURE6, &identity);
+ SetTransform(D3DTS_TEXTURE7, &identity);
+
+ for(int i = 0; i < 12; i++)
+ {
+ SetTransform(D3DTS_WORLDMATRIX(i), &identity);
+ }
+
+ for(int i = 0; i < 224; i++)
+ {
+ float zero[4] = {0, 0, 0, 0};
+
+ SetPixelShaderConstantF(i, zero, 1);
+ }
+
+ for(int i = 0; i < 256; i++)
+ {
+ float zero[4] = {0, 0, 0, 0};
+
+ SetVertexShaderConstantF(i, zero, 1);
+ }
+
+ for(int i = 0; i < 16; i++)
+ {
+ int zero[4] = {0, 0, 0, 0};
+
+ SetPixelShaderConstantI(i, zero, 1);
+ SetVertexShaderConstantI(i, zero, 1);
+ SetPixelShaderConstantB(i, &zero[0], 1);
+ SetVertexShaderConstantB(i, &zero[0], 1);
+ }
+
+ init = false;
+
+ if(!(behaviourFlags & D3DCREATE_FPU_PRESERVE))
+ {
+ configureFPU();
+ }
+
+ instancingEnabled = pixelShaderVersionX >= D3DPS_VERSION(3, 0);
+ }
+
+ Direct3DDevice9::~Direct3DDevice9()
+ {
+ delete renderer;
+ renderer = 0;
+ delete context;
+ context = 0;
+
+ d3d9->Release();
+ d3d9 = 0;
+
+ swapChain->unbind();
+ swapChain = 0;
+
+ if(depthStencil)
+ {
+ depthStencil->unbind();
+ depthStencil = 0;
+ }
+
+ if(autoDepthStencil)
+ {
+ autoDepthStencil->unbind();
+ autoDepthStencil = 0;
+ }
+
+ for(int index = 0; index < 4; index++)
+ {
+ if(renderTarget[index])
+ {
+ renderTarget[index]->unbind();
+ renderTarget[index] = 0;
+ }
+ }
+
+ if(vertexDeclaration)
+ {
+ vertexDeclaration->unbind();
+ vertexDeclaration = 0;
+ }
+
+ for(int i = 0; i < 16 + 4; i++)
+ {
+ if(texture[i])
+ {
+ texture[i]->unbind();
+ texture[i] = 0;
+ }
+ }
+
+ for(int i = 0; i < 16; i++)
+ {
+ if(dataStream[i])
+ {
+ dataStream[i]->unbind();
+ dataStream[i] = 0;
+ }
+ }
+
+ if(indexData)
+ {
+ indexData->unbind();
+ indexData = 0;
+ }
+
+ if(pixelShader)
+ {
+ pixelShader->unbind();
+ pixelShader = 0;
+ }
+
+ if(vertexShader)
+ {
+ vertexShader->unbind();
+ vertexShader = 0;
+ }
+
+ if(stateRecorder)
+ {
+ stateRecorder->unbind();
+ stateRecorder = 0;
+ }
+
+ palette.clear();
+
+ delete cursor;
+
+ DeleteCriticalSection(&criticalSection);
+ }
+
+ long Direct3DDevice9::QueryInterface(const IID &iid, void **object)
+ {
+ CriticalSection cs(this);
+
+ TRACE("const IID &iid = 0x%0.8p, void **object = 0x%0.8p", iid, object);
+
+ if(iid == IID_IDirect3DDevice9 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long Direct3DDevice9::AddRef()
+ {
+ TRACE("void");
+
+ return Unknown::AddRef();
+ }
+
+ unsigned long Direct3DDevice9::Release()
+ {
+ TRACE("void");
+
+ return Unknown::Release();
+ }
+
+ long Direct3DDevice9::BeginScene()
+ {
+ CriticalSection cs(this);
+
+ TRACE("void");
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::BeginStateBlock()
+ {
+ CriticalSection cs(this);
+
+ TRACE("void");
+
+ if(stateRecorder)
+ {
+ return INVALIDCALL();
+ }
+
+ stateRecorder = new Direct3DStateBlock9(this, (D3DSTATEBLOCKTYPE)0);
+
+ if(!stateRecorder)
+ {
+ return OUTOFMEMORY();
+ }
+
+ stateRecorder->bind();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::Clear(unsigned long count, const D3DRECT *rects, unsigned long flags, unsigned long color, float z, unsigned long stencil)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned long count = %d, const D3DRECT *rects = 0x%0.8p, unsigned long flags = 0x%0.8X, unsigned long color = 0x%0.8X, float z = %f, unsigned long stencil = %d", count, rects, flags, color, z, stencil);
+
+ if(rects == 0 && count != 0)
+ {
+ return INVALIDCALL();
+ }
+
+ if(flags & (D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL) && !depthStencil)
+ {
+ return INVALIDCALL();
+ }
+
+ if(flags & D3DCLEAR_STENCIL) // Check for stencil component
+ {
+ D3DSURFACE_DESC description;
+ depthStencil->GetDesc(&description);
+
+ switch(description.Format)
+ {
+ case D3DFMT_D15S1:
+ case D3DFMT_D24S8:
+ case D3DFMT_D24X8:
+ case D3DFMT_D24X4S4:
+ case D3DFMT_D24FS8:
+ case D3DFMT_S8_LOCKABLE: // FIXME: INVALIDCALL when trying to clear depth?
+ case D3DFMT_DF24:
+ case D3DFMT_DF16:
+ case D3DFMT_INTZ:
+ break;
+ case D3DFMT_D16_LOCKABLE:
+ case D3DFMT_D32:
+ case D3DFMT_D16:
+ case D3DFMT_D32F_LOCKABLE:
+ case D3DFMT_D32_LOCKABLE:
+ return INVALIDCALL();
+ default:
+ ASSERT(false);
+ }
+ }
+
+ if(!rects)
+ {
+ count = 1;
+
+ D3DRECT rect;
+
+ rect.x1 = viewport.X;
+ rect.x2 = viewport.X + viewport.Width;
+ rect.y1 = viewport.Y;
+ rect.y2 = viewport.Y + viewport.Height;
+
+ rects = ▭
+ }
+
+ for(unsigned int i = 0; i < count; i++)
+ {
+ D3DRECT rect = rects[i];
+
+ // Clamp against viewport
+ if(rect.x1 < (int)viewport.X) rect.x1 = viewport.X;
+ if(rect.x2 < (int)viewport.X) rect.x2 = viewport.X;
+ if(rect.x1 > (int)viewport.X + (int)viewport.Width) rect.x1 = viewport.X + viewport.Width;
+ if(rect.x2 > (int)viewport.X + (int)viewport.Width) rect.x2 = viewport.X + viewport.Width;
+
+ if(rect.y1 < (int)viewport.Y) rect.y1 = viewport.Y;
+ if(rect.y2 < (int)viewport.Y) rect.y2 = viewport.Y;
+ if(rect.y1 > (int)viewport.Y + (int)viewport.Height) rect.y1 = viewport.Y + viewport.Height;
+ if(rect.y2 > (int)viewport.Y + (int)viewport.Height) rect.y2 = viewport.Y + viewport.Height;
+
+ // Clamp against scissor rectangle
+ if(scissorEnable)
+ {
+ if(rect.x1 < (int)scissorRect.left) rect.x1 = scissorRect.left;
+ if(rect.x2 < (int)scissorRect.left) rect.x2 = scissorRect.left;
+ if(rect.x1 > (int)scissorRect.right) rect.x1 = scissorRect.right;
+ if(rect.x2 > (int)scissorRect.right) rect.x2 = scissorRect.right;
+
+ if(rect.y1 < (int)scissorRect.top) rect.y1 = scissorRect.top;
+ if(rect.y2 < (int)scissorRect.top) rect.y2 = scissorRect.top;
+ if(rect.y1 > (int)scissorRect.bottom) rect.y1 = scissorRect.bottom;
+ if(rect.y2 > (int)scissorRect.bottom) rect.y2 = scissorRect.bottom;
+ }
+
+ if(flags & D3DCLEAR_STENCIL)
+ {
+ depthStencil->clearStencilBuffer(stencil, 0xFF, rect.x1, rect.y1, rect.x2 - rect.x1, rect.y2 - rect.y1);
+ }
+
+ if(flags & D3DCLEAR_TARGET)
+ {
+ for(int index = 0; index < 4; index++)
+ {
+ if(renderTarget[index])
+ {
+ D3DSURFACE_DESC description;
+ renderTarget[index]->GetDesc(&description);
+
+ if(renderState[D3DRS_SRGBWRITEENABLE] != FALSE && index == 0 && Capabilities::isSRGBwritable(description.Format))
+ {
+ float r = (float)(color & 0x00FF0000) / 0x00FF0000;
+ float g = (float)(color & 0x0000FF00) / 0x0000FF00;
+ float b = (float)(color & 0x000000FF) / 0x000000FF;
+ float a = (float)(color & 0xFF000000) / 0xFF000000;
+
+ r = sw::linearToSRGB(r);
+ g = sw::linearToSRGB(g);
+ b = sw::linearToSRGB(b);
+
+ color = ((int)(a * 255) << 24) |
+ ((int)(r * 255) << 16) |
+ ((int)(g * 255) << 8) |
+ ((int)(b * 255) << 0);
+ }
+
+ renderTarget[index]->clearColorBuffer(color, 0xF, rect.x1, rect.y1, rect.x2 - rect.x1, rect.y2 - rect.y1);
+ }
+ }
+ }
+
+ if(flags & D3DCLEAR_ZBUFFER)
+ {
+ if(z > 1) z = 1;
+ if(z < 0) z = 0;
+
+ depthStencil->clearDepthBuffer(z, rect.x1, rect.y1, rect.x2 - rect.x1, rect.y2 - rect.y1);
+ }
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::ColorFill(IDirect3DSurface9 *surface, const RECT *rect, D3DCOLOR color)
+ {
+ CriticalSection cs(this);
+
+ TRACE("IDirect3DSurface9 *surface = 0x%0.8p, const RECT *rect = 0x%0.8p, D3DCOLOR color = 0x%0.8X", surface, rect, color);
+
+ if(!surface)
+ {
+ return INVALIDCALL();
+ }
+
+ D3DSURFACE_DESC description;
+
+ surface->GetDesc(&description);
+
+ if(description.Pool != D3DPOOL_DEFAULT)
+ {
+ return INVALIDCALL();
+ }
+
+ if(!rect)
+ {
+ RECT lock;
+
+ lock.left = 0;
+ lock.top = 0;
+ lock.right = description.Width;
+ lock.bottom = description.Height;
+
+ rect = &lock;
+ }
+
+ static_cast<Direct3DSurface9*>(surface)->fill(color, rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top);
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS *presentParameters, IDirect3DSwapChain9 **swapChain)
+ {
+ CriticalSection cs(this);
+
+ TRACE("D3DPRESENT_PARAMETERS *presentParameters = 0x%0.8p, IDirect3DSwapChain9 **swapChain = 0x%0.8p", presentParameters, swapChain);
+
+ if(!swapChain)
+ {
+ return INVALIDCALL();
+ }
+
+ *swapChain = 0;
+
+ if(!presentParameters)
+ {
+ return INVALIDCALL();
+ }
+
+ if(presentParameters->BackBufferCount > 3)
+ {
+ return INVALIDCALL(); // Maximum of three back buffers
+ }
+
+ *swapChain = new Direct3DSwapChain9(this, presentParameters);
+
+ if(!*swapChain)
+ {
+ return OUTOFMEMORY();
+ }
+
+ if(GetAvailableTextureMem() == 0)
+ {
+ delete *swapChain;
+ *swapChain = 0;
+
+ return OUTOFVIDEOMEMORY();
+ }
+
+ (*swapChain)->AddRef();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::CreateCubeTexture(unsigned int edgeLength, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DCubeTexture9 **cubeTexture, void **sharedHandle)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int edgeLength = %d, unsigned int levels = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DCubeTexture9 **cubeTexture = 0x%0.8p, void **sharedHandle = 0x%0.8p", edgeLength, levels, usage, format, pool, cubeTexture, sharedHandle);
+
+ *cubeTexture = 0;
+
+ if(edgeLength == 0 || (usage & D3DUSAGE_AUTOGENMIPMAP && levels > 1) || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_CUBETEXTURE, format) != D3D_OK)
+ {
+ return INVALIDCALL();
+ }
+
+ *cubeTexture = new Direct3DCubeTexture9(this, edgeLength, levels, usage, format, pool);
+
+ if(!*cubeTexture)
+ {
+ return OUTOFMEMORY();
+ }
+
+ if(GetAvailableTextureMem() == 0)
+ {
+ delete *cubeTexture;
+ *cubeTexture = 0;
+
+ return OUTOFVIDEOMEMORY();
+ }
+
+ (*cubeTexture)->AddRef();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::CreateDepthStencilSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, unsigned long multiSampleQuality, int discard, IDirect3DSurface9 **surface, void **sharedHandle)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int width = %d, unsigned int height = %d, D3DFORMAT format = %d, D3DMULTISAMPLE_TYPE multiSample = %d, unsigned long multiSampleQuality = %d, int discard = %d, IDirect3DSurface9 **surface = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, format, multiSample, multiSampleQuality, discard, surface, sharedHandle);
+
+ *surface = 0;
+
+ if(width == 0 || height == 0 || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, format) != D3D_OK || height > OUTLINE_RESOLUTION)
+ {
+ return INVALIDCALL();
+ }
+
+ bool lockable = false;
+
+ switch(format)
+ {
+ case D3DFMT_D15S1:
+ case D3DFMT_D24S8:
+ case D3DFMT_D24X8:
+ case D3DFMT_D24X4S4:
+ case D3DFMT_D24FS8:
+ case D3DFMT_D32:
+ case D3DFMT_D16:
+ case D3DFMT_DF24:
+ case D3DFMT_DF16:
+ case D3DFMT_INTZ:
+ lockable = false;
+ break;
+ case D3DFMT_S8_LOCKABLE:
+ case D3DFMT_D16_LOCKABLE:
+ case D3DFMT_D32F_LOCKABLE:
+ case D3DFMT_D32_LOCKABLE:
+ lockable = true;
+ break;
+ default:
+ ASSERT(false);
+ }
+
+ *surface = new Direct3DSurface9(this, this, width, height, format, D3DPOOL_DEFAULT, multiSample, multiSampleQuality, lockable, D3DUSAGE_DEPTHSTENCIL);
+
+ if(!*surface)
+ {
+ return OUTOFMEMORY();
+ }
+
+ if(GetAvailableTextureMem() == 0)
+ {
+ delete *surface;
+ *surface = 0;
+
+ return OUTOFVIDEOMEMORY();
+ }
+
+ (*surface)->AddRef();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::CreateIndexBuffer(unsigned int length, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer9 **indexBuffer, void **sharedHandle)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int length = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DIndexBuffer9 **indexBuffer = 0x%0.8p, void **sharedHandle = 0x%0.8p", length, usage, format, pool, indexBuffer, sharedHandle);
+
+ *indexBuffer = new Direct3DIndexBuffer9(this, length, usage, format, pool);
+
+ if(!*indexBuffer)
+ {
+ return OUTOFMEMORY();
+ }
+
+ if(GetAvailableTextureMem() == 0)
+ {
+ delete *indexBuffer;
+ *indexBuffer = 0;
+
+ return OUTOFVIDEOMEMORY();
+ }
+
+ (*indexBuffer)->AddRef();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::CreateOffscreenPlainSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DPOOL pool, IDirect3DSurface9 **surface, void **sharedHandle)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int width = %d, unsigned int height = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DSurface9 **surface = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, format, pool, surface, sharedHandle);
+
+ *surface = 0;
+
+ if(width == 0 || height == 0 || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, format) != D3D_OK) // FIXME: Allow all formats supported by runtime/REF
+ {
+ return INVALIDCALL();
+ }
+
+ if(pool == D3DPOOL_MANAGED)
+ {
+ return INVALIDCALL();
+ }
+
+ *surface = new Direct3DSurface9(this, this, width, height, format, pool, D3DMULTISAMPLE_NONE, 0, true, 0);
+
+ if(!*surface)
+ {
+ return OUTOFMEMORY();
+ }
+
+ if(GetAvailableTextureMem() == 0)
+ {
+ delete *surface;
+ *surface = 0;
+
+ return OUTOFVIDEOMEMORY();
+ }
+
+ (*surface)->AddRef();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::CreatePixelShader(const unsigned long *function, IDirect3DPixelShader9 **shader)
+ {
+ CriticalSection cs(this);
+
+ TRACE("const unsigned long *function = 0x%0.8p, IDirect3DPixelShader9 **shader = 0x%0.8p", function, shader);
+
+ if(!shader)
+ {
+ return INVALIDCALL();
+ }
+
+ *shader = 0;
+
+ if(!sw::PixelShader::validate(function) || function[0] > pixelShaderVersionX)
+ {
+ return INVALIDCALL(); // Shader contains unsupported operations
+ }
+
+ *shader = new Direct3DPixelShader9(this, function);
+
+ if(!*shader)
+ {
+ return OUTOFMEMORY();
+ }
+
+ (*shader)->AddRef();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::CreateQuery(D3DQUERYTYPE type, IDirect3DQuery9 **query)
+ {
+ CriticalSection cs(this);
+
+ TRACE("D3DQUERYTYPE type = %d, IDirect3DQuery9 **query = 0x%0.8p", type, query);
+
+ if(query == 0) // Support checked
+ {
+ switch(type)
+ {
+ case D3DQUERYTYPE_VCACHE: return D3D_OK;
+ case D3DQUERYTYPE_RESOURCEMANAGER: return NOTAVAILABLE();
+ case D3DQUERYTYPE_VERTEXSTATS: return NOTAVAILABLE();
+ case D3DQUERYTYPE_EVENT: return D3D_OK;
+ case D3DQUERYTYPE_OCCLUSION: return D3D_OK;
+ case D3DQUERYTYPE_TIMESTAMP: return D3D_OK;
+ case D3DQUERYTYPE_TIMESTAMPDISJOINT: return D3D_OK;
+ case D3DQUERYTYPE_TIMESTAMPFREQ: return D3D_OK;
+ case D3DQUERYTYPE_PIPELINETIMINGS: return NOTAVAILABLE();
+ case D3DQUERYTYPE_INTERFACETIMINGS: return NOTAVAILABLE();
+ case D3DQUERYTYPE_VERTEXTIMINGS: return NOTAVAILABLE();
+ case D3DQUERYTYPE_PIXELTIMINGS: return NOTAVAILABLE();
+ case D3DQUERYTYPE_BANDWIDTHTIMINGS: return NOTAVAILABLE();
+ case D3DQUERYTYPE_CACHEUTILIZATION: return NOTAVAILABLE();
+ default: ASSERT(false); return NOTAVAILABLE();
+ }
+ }
+ else
+ {
+ switch(type)
+ {
+ case D3DQUERYTYPE_VCACHE: break;
+ case D3DQUERYTYPE_RESOURCEMANAGER: return NOTAVAILABLE();
+ case D3DQUERYTYPE_VERTEXSTATS: return NOTAVAILABLE();
+ case D3DQUERYTYPE_EVENT: break;
+ case D3DQUERYTYPE_OCCLUSION: break;
+ case D3DQUERYTYPE_TIMESTAMP: break;
+ case D3DQUERYTYPE_TIMESTAMPDISJOINT: break;
+ case D3DQUERYTYPE_TIMESTAMPFREQ: break;
+ case D3DQUERYTYPE_PIPELINETIMINGS: return NOTAVAILABLE();
+ case D3DQUERYTYPE_INTERFACETIMINGS: return NOTAVAILABLE();
+ case D3DQUERYTYPE_VERTEXTIMINGS: return NOTAVAILABLE();
+ case D3DQUERYTYPE_PIXELTIMINGS: return NOTAVAILABLE();
+ case D3DQUERYTYPE_BANDWIDTHTIMINGS: return NOTAVAILABLE();
+ case D3DQUERYTYPE_CACHEUTILIZATION: return NOTAVAILABLE();
+ default: ASSERT(false); return NOTAVAILABLE();
+ }
+
+ *query = new Direct3DQuery9(this, type);
+
+ if(!*query)
+ {
+ return OUTOFMEMORY();
+ }
+
+ (*query)->AddRef();
+
+ return D3D_OK;
+ }
+ }
+
+ long Direct3DDevice9::CreateRenderTarget(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, unsigned long multiSampleQuality, int lockable, IDirect3DSurface9 **surface, void **sharedHandle)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int width = %d, unsigned int height = %d, D3DFORMAT format = %d, D3DMULTISAMPLE_TYPE multiSample = %d, unsigned long multiSampleQuality = %d, int lockable = %d, IDirect3DSurface9 **surface = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, format, multiSample, multiSampleQuality, lockable, surface, sharedHandle);
+
+ *surface = 0;
+
+ if(width == 0 || height == 0 || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, format) != D3D_OK || height > OUTLINE_RESOLUTION)
+ {
+ return INVALIDCALL();
+ }
+
+ *surface = new Direct3DSurface9(this, this, width, height, format, D3DPOOL_DEFAULT, multiSample, multiSampleQuality, lockable != FALSE, D3DUSAGE_RENDERTARGET);
+
+ if(!*surface)
+ {
+ return OUTOFMEMORY();
+ }
+
+ if(GetAvailableTextureMem() == 0)
+ {
+ delete *surface;
+ *surface = 0;
+
+ return OUTOFVIDEOMEMORY();
+ }
+
+ (*surface)->AddRef();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::CreateStateBlock(D3DSTATEBLOCKTYPE type, IDirect3DStateBlock9 **stateBlock)
+ {
+ CriticalSection cs(this);
+
+ TRACE("D3DSTATEBLOCKTYPE type = %d, IDirect3DStateBlock9 **stateBlock = 0x%0.8p", type, stateBlock);
+
+ *stateBlock = new Direct3DStateBlock9(this, type);
+
+ if(!*stateBlock)
+ {
+ return OUTOFMEMORY();
+ }
+
+ (*stateBlock)->AddRef();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::CreateTexture(unsigned int width, unsigned int height, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DTexture9 **texture, void **sharedHandle)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int width = %d, unsigned int height = %d, unsigned int levels = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DTexture9 **texture = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, levels, usage, format, pool, texture, sharedHandle);
+
+ *texture = 0;
+
+ if(width == 0 || height == 0 || (usage & D3DUSAGE_AUTOGENMIPMAP && levels > 1) || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_TEXTURE, format) != D3D_OK)
+ {
+ return INVALIDCALL();
+ }
+
+ *texture = new Direct3DTexture9(this, width, height, levels, usage, format, pool);
+
+ if(!*texture)
+ {
+ return OUTOFMEMORY();
+ }
+
+ if(GetAvailableTextureMem() == 0)
+ {
+ delete *texture;
+ *texture = 0;
+
+ return OUTOFVIDEOMEMORY();
+ }
+
+ (*texture)->AddRef();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::CreateVertexBuffer(unsigned int length, unsigned long usage, unsigned long FVF, D3DPOOL pool, IDirect3DVertexBuffer9 **vertexBuffer, void **sharedHandle)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int length = %d, unsigned long usage = %d, unsigned long FVF = 0x%0.8X, D3DPOOL pool = %d, IDirect3DVertexBuffer9 **vertexBuffer = 0x%0.8p, void **sharedHandle = 0x%0.8p", length, usage, FVF, pool, vertexBuffer, sharedHandle);
+
+ *vertexBuffer = new Direct3DVertexBuffer9(this, length, usage, FVF, pool);
+
+ if(!*vertexBuffer)
+ {
+ return OUTOFMEMORY();
+ }
+
+ if(GetAvailableTextureMem() == 0)
+ {
+ delete *vertexBuffer;
+ *vertexBuffer = 0;
+
+ return OUTOFVIDEOMEMORY();
+ }
+
+ (*vertexBuffer)->AddRef();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::CreateVertexDeclaration(const D3DVERTEXELEMENT9 *vertexElements, IDirect3DVertexDeclaration9 **declaration)
+ {
+ CriticalSection cs(this);
+
+ TRACE("const D3DVERTEXELEMENT9 *vertexElements = 0x%0.8p, IDirect3DVertexDeclaration9 **declaration = 0x%0.8p", vertexElements, declaration);
+
+ if(!declaration)
+ {
+ return INVALIDCALL();
+ }
+
+ const D3DVERTEXELEMENT9 *element = vertexElements;
+
+ while(element->Stream != 0xFF)
+ {
+ if(element->Type > D3DDECLTYPE_UNUSED) // FIXME: Check other fields too
+ {
+ return FAIL();
+ }
+
+ element++;
+ }
+
+ *declaration = new Direct3DVertexDeclaration9(this, vertexElements);
+
+ if(!*declaration)
+ {
+ return OUTOFMEMORY();
+ }
+
+ (*declaration)->AddRef();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::CreateVertexShader(const unsigned long *function, IDirect3DVertexShader9 **shader)
+ {
+ CriticalSection cs(this);
+
+ TRACE("const unsigned long *function = 0x%0.8p, IDirect3DVertexShader9 **shader = 0x%0.8p", function, shader);
+
+ if(!shader)
+ {
+ return INVALIDCALL();
+ }
+
+ *shader = 0;
+
+ if(!sw::VertexShader::validate(function) || function[0] > vertexShaderVersionX)
+ {
+ return INVALIDCALL(); // Shader contains unsupported operations
+ }
+
+ *shader = new Direct3DVertexShader9(this, function);
+
+ if(!*shader)
+ {
+ return OUTOFMEMORY();
+ }
+
+ (*shader)->AddRef();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::CreateVolumeTexture(unsigned int width, unsigned int height, unsigned int depth, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DVolumeTexture9 **volumeTexture, void **sharedHandle)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int width = %d, unsigned int height = %d, unsigned int depth = %d, unsigned int levels = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DVolumeTexture9 **volumeTexture = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, depth, levels, usage, format, pool, volumeTexture, sharedHandle);
+
+ *volumeTexture = 0;
+
+ if(width == 0 || height == 0 || depth == 0 || (usage & D3DUSAGE_AUTOGENMIPMAP && levels > 1) || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_VOLUMETEXTURE, format) != D3D_OK)
+ {
+ return INVALIDCALL();
+ }
+
+ *volumeTexture = new Direct3DVolumeTexture9(this, width, height, depth, levels, usage, format, pool);
+
+ if(!*volumeTexture)
+ {
+ return OUTOFMEMORY();
+ }
+
+ if(GetAvailableTextureMem() == 0)
+ {
+ delete *volumeTexture;
+ *volumeTexture = 0;
+
+ return OUTOFVIDEOMEMORY();
+ }
+
+ (*volumeTexture)->AddRef();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::DeletePatch(unsigned int handle)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int handle = %d", handle);
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::DrawIndexedPrimitive(D3DPRIMITIVETYPE type, int baseVertexIndex, unsigned int minIndex, unsigned int numVertices, unsigned int startIndex, unsigned int primitiveCount)
+ {
+ CriticalSection cs(this);
+
+ TRACE("D3DPRIMITIVETYPE type = %d, int baseVertexIndex = %d, unsigned int minIndex = %d, unsigned int numVertices = %d, unsigned int startIndex = %d, unsigned int primitiveCount = %d", type, baseVertexIndex, minIndex, numVertices, startIndex, primitiveCount);
+
+ if(!indexData)
+ {
+ return INVALIDCALL();
+ }
+
+ if(!bindResources(indexData) || !primitiveCount)
+ {
+ return D3D_OK;
+ }
+
+ unsigned int indexOffset = startIndex * (indexData->is32Bit() ? 4 : 2); // FIXME: Doesn't take stream frequencies into account
+
+ sw::Context::DrawType drawType;
+
+ if(indexData->is32Bit())
+ {
+ switch(type)
+ {
+ case D3DPT_POINTLIST: drawType = sw::Context::DRAW_INDEXEDPOINTLIST32; break;
+ case D3DPT_LINELIST: drawType = sw::Context::DRAW_INDEXEDLINELIST32; break;
+ case D3DPT_LINESTRIP: drawType = sw::Context::DRAW_INDEXEDLINESTRIP32; break;
+ case D3DPT_TRIANGLELIST: drawType = sw::Context::DRAW_INDEXEDTRIANGLELIST32; break;
+ case D3DPT_TRIANGLESTRIP: drawType = sw::Context::DRAW_INDEXEDTRIANGLESTRIP32; break;
+ case D3DPT_TRIANGLEFAN: drawType = sw::Context::DRAW_INDEXEDTRIANGLEFAN32; break;
+ default:
+ ASSERT(false);
+ }
+ }
+ else
+ {
+ switch(type)
+ {
+ case D3DPT_POINTLIST: drawType = sw::Context::DRAW_INDEXEDPOINTLIST16; break;
+ case D3DPT_LINELIST: drawType = sw::Context::DRAW_INDEXEDLINELIST16; break;
+ case D3DPT_LINESTRIP: drawType = sw::Context::DRAW_INDEXEDLINESTRIP16; break;
+ case D3DPT_TRIANGLELIST: drawType = sw::Context::DRAW_INDEXEDTRIANGLELIST16; break;
+ case D3DPT_TRIANGLESTRIP: drawType = sw::Context::DRAW_INDEXEDTRIANGLESTRIP16; break;
+ case D3DPT_TRIANGLEFAN: drawType = sw::Context::DRAW_INDEXEDTRIANGLEFAN16; break;
+ default:
+ ASSERT(false);
+ }
+ }
+
+ if((streamSourceFreq[0] & D3DSTREAMSOURCE_INDEXEDDATA) && instanceData())
+ {
+ int instanceCount = (streamSourceFreq[0] & ~D3DSTREAMSOURCE_INDEXEDDATA);
+
+ for(int instance = 0; instance < instanceCount; instance++)
+ {
+ bindVertexStreams(baseVertexIndex, true, instance);
+ renderer->draw(drawType, indexOffset, primitiveCount, instance == 0);
+ }
+ }
+ else
+ {
+ bindVertexStreams(baseVertexIndex, false, 0);
+ renderer->draw(drawType, indexOffset, primitiveCount);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE type, unsigned int minIndex, unsigned int numVertices, unsigned int primitiveCount, const void *indexData, D3DFORMAT indexDataFormat, const void *vertexStreamZeroData, unsigned int vertexStreamZeroStride)
+ {
+ CriticalSection cs(this);
+
+ TRACE("D3DPRIMITIVETYPE type = %d, unsigned int minIndex = %d, unsigned int numVertices = %d, unsigned int primitiveCount = %d, const void *indexData = 0x%0.8p, D3DFORMAT indexDataFormat = %d, const void *vertexStreamZeroData = 0x%0.8p, unsigned int vertexStreamZeroStride = %d", type, minIndex, numVertices, primitiveCount, indexData, indexDataFormat, vertexStreamZeroData, vertexStreamZeroStride);
+
+ if(!vertexStreamZeroData || !indexData)
+ {
+ return INVALIDCALL();
+ }
+
+ int length = (minIndex + numVertices) * vertexStreamZeroStride;
+
+ Direct3DVertexBuffer9 *vertexBuffer = new Direct3DVertexBuffer9(this, length, 0, 0, D3DPOOL_DEFAULT);
+
+ void *data;
+ vertexBuffer->Lock(0, 0, &data, 0);
+ memcpy(data, vertexStreamZeroData, length);
+ vertexBuffer->Unlock();
+
+ SetStreamSource(0, vertexBuffer, 0, vertexStreamZeroStride);
+
+ switch(type)
+ {
+ case D3DPT_POINTLIST: length = primitiveCount; break;
+ case D3DPT_LINELIST: length = primitiveCount * 2; break;
+ case D3DPT_LINESTRIP: length = primitiveCount + 1; break;
+ case D3DPT_TRIANGLELIST: length = primitiveCount * 3; break;
+ case D3DPT_TRIANGLESTRIP: length = primitiveCount + 2; break;
+ case D3DPT_TRIANGLEFAN: length = primitiveCount + 2; break;
+ default:
+ ASSERT(false);
+ }
+
+ length *= indexDataFormat == D3DFMT_INDEX32 ? 4 : 2;
+
+ Direct3DIndexBuffer9 *indexBuffer = new Direct3DIndexBuffer9(this, length, 0, indexDataFormat, D3DPOOL_DEFAULT);
+
+ indexBuffer->Lock(0, 0, &data, 0);
+ memcpy(data, indexData, length);
+ indexBuffer->Unlock();
+
+ SetIndices(indexBuffer);
+
+ if(!bindResources(indexBuffer) || !primitiveCount)
+ {
+ vertexBuffer->Release();
+
+ return D3D_OK;
+ }
+
+ sw::Context::DrawType drawType;
+
+ if(indexDataFormat == D3DFMT_INDEX32)
+ {
+ switch(type)
+ {
+ case D3DPT_POINTLIST: drawType = sw::Context::DRAW_INDEXEDPOINTLIST32; break;
+ case D3DPT_LINELIST: drawType = sw::Context::DRAW_INDEXEDLINELIST32; break;
+ case D3DPT_LINESTRIP: drawType = sw::Context::DRAW_INDEXEDLINESTRIP32; break;
+ case D3DPT_TRIANGLELIST: drawType = sw::Context::DRAW_INDEXEDTRIANGLELIST32; break;
+ case D3DPT_TRIANGLESTRIP: drawType = sw::Context::DRAW_INDEXEDTRIANGLESTRIP32; break;
+ case D3DPT_TRIANGLEFAN: drawType = sw::Context::DRAW_INDEXEDTRIANGLEFAN32; break;
+ default:
+ ASSERT(false);
+ }
+ }
+ else
+ {
+ switch(type)
+ {
+ case D3DPT_POINTLIST: drawType = sw::Context::DRAW_INDEXEDPOINTLIST16; break;
+ case D3DPT_LINELIST: drawType = sw::Context::DRAW_INDEXEDLINELIST16; break;
+ case D3DPT_LINESTRIP: drawType = sw::Context::DRAW_INDEXEDLINESTRIP16; break;
+ case D3DPT_TRIANGLELIST: drawType = sw::Context::DRAW_INDEXEDTRIANGLELIST16; break;
+ case D3DPT_TRIANGLESTRIP: drawType = sw::Context::DRAW_INDEXEDTRIANGLESTRIP16; break;
+ case D3DPT_TRIANGLEFAN: drawType = sw::Context::DRAW_INDEXEDTRIANGLEFAN16; break;
+ default:
+ ASSERT(false);
+ }
+ }
+
+ bindVertexStreams(0, false, 0);
+ renderer->draw(drawType, 0, primitiveCount);
+
+ SetStreamSource(0, 0, 0, 0);
+ SetIndices(0);
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::DrawPrimitive(D3DPRIMITIVETYPE primitiveType, unsigned int startVertex, unsigned int primitiveCount)
+ {
+ CriticalSection cs(this);
+
+ TRACE("D3DPRIMITIVETYPE primitiveType = %d, unsigned int startVertex = %d, unsigned int primitiveCount = %d", primitiveType, startVertex, primitiveCount);
+
+ if(!bindResources(0) || !primitiveCount)
+ {
+ return D3D_OK;
+ }
+
+ sw::Context::DrawType drawType;
+
+ switch(primitiveType)
+ {
+ case D3DPT_POINTLIST: drawType = sw::Context::DRAW_POINTLIST; break;
+ case D3DPT_LINELIST: drawType = sw::Context::DRAW_LINELIST; break;
+ case D3DPT_LINESTRIP: drawType = sw::Context::DRAW_LINESTRIP; break;
+ case D3DPT_TRIANGLELIST: drawType = sw::Context::DRAW_TRIANGLELIST; break;
+ case D3DPT_TRIANGLESTRIP: drawType = sw::Context::DRAW_TRIANGLESTRIP; break;
+ case D3DPT_TRIANGLEFAN: drawType = sw::Context::DRAW_TRIANGLEFAN; break;
+ default:
+ ASSERT(false);
+ }
+
+ bindVertexStreams(startVertex, false, 0);
+ renderer->draw(drawType, 0, primitiveCount);
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::DrawPrimitiveUP(D3DPRIMITIVETYPE primitiveType, unsigned int primitiveCount, const void *vertexStreamZeroData, unsigned int vertexStreamZeroStride)
+ {
+ CriticalSection cs(this);
+
+ TRACE("D3DPRIMITIVETYPE primitiveType = %d, unsigned int primitiveCount = %d, const void *vertexStreamZeroData = 0x%0.8p, unsigned int vertexStreamZeroStride = %d", primitiveType, primitiveCount, vertexStreamZeroData, vertexStreamZeroStride);
+
+ if(!vertexStreamZeroData)
+ {
+ return INVALIDCALL();
+ }
+
+ IDirect3DVertexBuffer9 *vertexBuffer = 0;
+ int length = 0;
+
+ switch(primitiveType)
+ {
+ case D3DPT_POINTLIST: length = primitiveCount; break;
+ case D3DPT_LINELIST: length = primitiveCount * 2; break;
+ case D3DPT_LINESTRIP: length = primitiveCount + 1; break;
+ case D3DPT_TRIANGLELIST: length = primitiveCount * 3; break;
+ case D3DPT_TRIANGLESTRIP: length = primitiveCount + 2; break;
+ case D3DPT_TRIANGLEFAN: length = primitiveCount + 2; break;
+ default:
+ ASSERT(false);
+ }
+
+ length *= vertexStreamZeroStride;
+
+ CreateVertexBuffer(length, 0, 0, D3DPOOL_DEFAULT, &vertexBuffer, 0);
+
+ void *data;
+ vertexBuffer->Lock(0, 0, &data, 0);
+ memcpy(data, vertexStreamZeroData, length);
+ vertexBuffer->Unlock();
+
+ SetStreamSource(0, vertexBuffer, 0, vertexStreamZeroStride);
+
+ if(!bindResources(0) || !primitiveCount)
+ {
+ vertexBuffer->Release();
+
+ return D3D_OK;
+ }
+
+ sw::Context::DrawType drawType;
+
+ switch(primitiveType)
+ {
+ case D3DPT_POINTLIST: drawType = sw::Context::DRAW_POINTLIST; break;
+ case D3DPT_LINELIST: drawType = sw::Context::DRAW_LINELIST; break;
+ case D3DPT_LINESTRIP: drawType = sw::Context::DRAW_LINESTRIP; break;
+ case D3DPT_TRIANGLELIST: drawType = sw::Context::DRAW_TRIANGLELIST; break;
+ case D3DPT_TRIANGLESTRIP: drawType = sw::Context::DRAW_TRIANGLESTRIP; break;
+ case D3DPT_TRIANGLEFAN: drawType = sw::Context::DRAW_TRIANGLEFAN; break;
+ default:
+ ASSERT(false);
+ }
+
+ bindVertexStreams(0, false, 0);
+ renderer->draw(drawType, 0, primitiveCount);
+
+ SetStreamSource(0, 0, 0, 0);
+ vertexBuffer->Release();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::DrawRectPatch(unsigned int handle, const float *numSegs, const D3DRECTPATCH_INFO *rectPatchInfo)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int handle = %d, const float *numSegs = 0x%0.8p, const D3DRECTPATCH_INFO *rectPatchInfo = 0x%0.8p", handle, numSegs, rectPatchInfo);
+
+ if(!numSegs || !rectPatchInfo)
+ {
+ return INVALIDCALL();
+ }
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::DrawTriPatch(unsigned int handle, const float *numSegs, const D3DTRIPATCH_INFO *triPatchInfo)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int handle = %d, const float *numSegs = 0x%0.8p, const D3DTRIPATCH_INFO *triPatchInfo = 0x%0.8p", handle, numSegs, triPatchInfo);
+
+ if(!numSegs || !triPatchInfo)
+ {
+ return INVALIDCALL();
+ }
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::EndScene()
+ {
+ CriticalSection cs(this);
+
+ TRACE("void");
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::EndStateBlock(IDirect3DStateBlock9 **stateBlock)
+ {
+ CriticalSection cs(this);
+
+ TRACE("IDirect3DStateBlock9 **stateBlock = 0x%0.8p", stateBlock);
+
+ if(!stateBlock)
+ {
+ return INVALIDCALL();
+ }
+
+ *stateBlock = 0;
+
+ if(!stateRecorder)
+ {
+ return INVALIDCALL();
+ }
+
+ *stateBlock = stateRecorder;
+ stateRecorder->AddRef();
+ stateRecorder->unbind();
+ stateRecorder = 0; // Stop recording
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::EvictManagedResources()
+ {
+ CriticalSection cs(this);
+
+ TRACE("void");
+
+ // UNIMPLEMENTED(); // FIXME
+
+ return D3D_OK;
+ }
+
+ unsigned int Direct3DDevice9::GetAvailableTextureMem()
+ {
+ CriticalSection cs(this);
+
+ TRACE("void");
+
+ int availableMemory = textureMemory - Direct3DResource9::getMemoryUsage();
+ if(availableMemory < 0) availableMemory = 0;
+
+ // Round to nearest MB
+ return (availableMemory + 0x80000) & 0xFFF00000;
+ }
+
+ long Direct3DDevice9::GetBackBuffer(unsigned int swapChainIndex, unsigned int backBufferIndex, D3DBACKBUFFER_TYPE type, IDirect3DSurface9 **backBuffer)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int swapChainIndex = %d, unsigned int backBufferIndex = %d, D3DBACKBUFFER_TYPE type = %d, IDirect3DSurface9 **backBuffer = 0x%0.8p", swapChainIndex, backBufferIndex, type, backBuffer);
+
+ if(swapChainIndex >= GetNumberOfSwapChains())
+ {
+ return INVALIDCALL();
+ }
+
+ return swapChain->GetBackBuffer(backBufferIndex, type, backBuffer);
+ }
+
+ long Direct3DDevice9::GetClipPlane(unsigned long index, float *plane)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned long index = %d, float *plane = 0x%0.8p", index, plane);
+
+ if(!plane || index >= 6)
+ {
+ return INVALIDCALL();
+ }
+
+ plane[0] = this->plane[index][0];
+ plane[1] = this->plane[index][1];
+ plane[2] = this->plane[index][2];
+ plane[3] = this->plane[index][3];
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetClipStatus(D3DCLIPSTATUS9 *clipStatus)
+ {
+ CriticalSection cs(this);
+
+ TRACE("D3DCLIPSTATUS9 *clipStatus = 0x%0.8p", clipStatus);
+
+ if(!clipStatus)
+ {
+ return INVALIDCALL();
+ }
+
+ *clipStatus = this->clipStatus;
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS *parameters)
+ {
+ CriticalSection cs(this);
+
+ TRACE("D3DDEVICE_CREATION_PARAMETERS *parameters = 0x%0.8p", parameters);
+
+ if(!parameters)
+ {
+ return INVALIDCALL();
+ }
+
+ parameters->AdapterOrdinal = adapter;
+ parameters->BehaviorFlags = behaviourFlags;
+ parameters->DeviceType = deviceType;
+ parameters->hFocusWindow = focusWindow;
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetCurrentTexturePalette(unsigned int *paletteNumber)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int *paletteNumber = 0x%0.8p", paletteNumber);
+
+ if(!paletteNumber)
+ {
+ return INVALIDCALL();
+ }
+
+ *paletteNumber = currentPalette;
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetDepthStencilSurface(IDirect3DSurface9 **depthStencilSurface)
+ {
+ CriticalSection cs(this);
+
+ TRACE("IDirect3DSurface9 **depthStencilSurface = 0x%0.8p", depthStencilSurface);
+
+ if(!depthStencilSurface)
+ {
+ return INVALIDCALL();
+ }
+
+ *depthStencilSurface = depthStencil;
+
+ if(depthStencil)
+ {
+ depthStencil->AddRef();
+ }
+ else
+ {
+ return NOTFOUND();
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetDeviceCaps(D3DCAPS9 *caps)
+ {
+ CriticalSection cs(this);
+
+ TRACE("D3DCAPS9 *caps = 0x%0.8p", caps);
+
+ return d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, caps);
+ }
+
+ long Direct3DDevice9::GetDirect3D(IDirect3D9 **d3d9)
+ {
+ CriticalSection cs(this);
+
+ TRACE("IDirect3D9 **d3d9 = 0x%0.8p", d3d9);
+
+ if(!d3d9)
+ {
+ return INVALIDCALL();
+ }
+
+ *d3d9 = this->d3d9;
+ this->d3d9->AddRef();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetDisplayMode(unsigned int index, D3DDISPLAYMODE *mode)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int index = %d, D3DDISPLAYMODE *mode = 0x%0.8p", index, mode);
+
+ if(index >= GetNumberOfSwapChains())
+ {
+ return INVALIDCALL();
+ }
+
+ return swapChain->GetDisplayMode(mode);
+ }
+
+ long Direct3DDevice9::GetFrontBufferData(unsigned int index, IDirect3DSurface9 *destSurface)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int index = %d, IDirect3DSurface9 *destSurface = %p", index, destSurface);
+
+ if(index >= GetNumberOfSwapChains())
+ {
+ return INVALIDCALL();
+ }
+
+ return swapChain->GetFrontBufferData(destSurface);
+ }
+
+ long Direct3DDevice9::GetFVF(unsigned long *FVF)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned long *FVF = 0x%0.8p", FVF);
+
+ if(!FVF)
+ {
+ return INVALIDCALL();
+ }
+
+ if(vertexDeclaration)
+ {
+ *FVF = vertexDeclaration->getFVF();
+ }
+ else
+ {
+ *FVF = 0;
+ }
+
+ return D3D_OK;
+ }
+
+ void Direct3DDevice9::GetGammaRamp(unsigned int index, D3DGAMMARAMP *ramp)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int index = %d, D3DGAMMARAMP *ramp = 0x%0.8p", index, ramp);
+
+ if(!ramp || index >= GetNumberOfSwapChains())
+ {
+ return;
+ }
+
+ swapChain->getGammaRamp((sw::GammaRamp*)ramp);
+ }
+
+ long Direct3DDevice9::GetIndices(IDirect3DIndexBuffer9 **indexData)
+ {
+ CriticalSection cs(this);
+
+ TRACE("IDirect3DIndexBuffer9 **indexData = 0x%0.8p", indexData);
+
+ if(!indexData)
+ {
+ return INVALIDCALL();
+ }
+
+ *indexData = this->indexData;
+
+ if(this->indexData)
+ {
+ this->indexData->AddRef();
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetLight(unsigned long index, D3DLIGHT9 *light)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned long index = %d, D3DLIGHT9 *light = 0x%0.8p", index, light);
+
+ if(!light)
+ {
+ return INVALIDCALL();
+ }
+
+ if(!this->light.exists(index))
+ {
+ return INVALIDCALL();
+ }
+
+ *light = this->light[index];
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetLightEnable(unsigned long index, int *enable)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned long index = %d, int *enable = 0x%0.8p", index, enable);
+
+ if(!enable)
+ {
+ return INVALIDCALL();
+ }
+
+ if(!light.exists(index))
+ {
+ return INVALIDCALL();
+ }
+
+ *enable = light[index].enable ? 128 : 0;
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetMaterial(D3DMATERIAL9 *material)
+ {
+ CriticalSection cs(this);
+
+ TRACE("D3DMATERIAL9 *material = 0x%0.8p", material);
+
+ if(!material)
+ {
+ return INVALIDCALL();
+ }
+
+ *material = this->material;
+
+ return D3D_OK;
+ }
+
+ float Direct3DDevice9::GetNPatchMode()
+ {
+ CriticalSection cs(this);
+
+ TRACE("void");
+
+ return 0.0f; // FIXME: Unimplemented
+ }
+
+ unsigned int Direct3DDevice9::GetNumberOfSwapChains()
+ {
+ CriticalSection cs(this);
+
+ TRACE("void");
+
+ return 1;
+ }
+
+ long Direct3DDevice9::GetPaletteEntries(unsigned int paletteNumber, PALETTEENTRY *entries)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int paletteNumber = %d, PALETTEENTRY *entries = 0x%0.8p", paletteNumber, entries);
+
+ if(paletteNumber > 0xFFFF || !entries)
+ {
+ return INVALIDCALL();
+ }
+
+ for(int i = 0; i < 256; i++)
+ {
+ entries[i] = palette[paletteNumber].entry[i];
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetPixelShader(IDirect3DPixelShader9 **shader)
+ {
+ CriticalSection cs(this);
+
+ TRACE("IDirect3DPixelShader9 **shader = 0x%0.8p", shader);
+
+ if(!shader)
+ {
+ return INVALIDCALL();
+ }
+
+ if(pixelShader)
+ {
+ pixelShader->AddRef();
+ }
+
+ *shader = pixelShader;
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetPixelShaderConstantB(unsigned int startRegister, int *constantData, unsigned int count)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ if(!constantData)
+ {
+ return INVALIDCALL();
+ }
+
+ for(unsigned int i = 0; i < count; i++)
+ {
+ constantData[i] = pixelShaderConstantB[startRegister + i];
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetPixelShaderConstantF(unsigned int startRegister, float *constantData, unsigned int count)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ if(!constantData)
+ {
+ return INVALIDCALL();
+ }
+
+ for(unsigned int i = 0; i < count; i++)
+ {
+ constantData[i * 4 + 0] = pixelShaderConstantF[startRegister + i][0];
+ constantData[i * 4 + 1] = pixelShaderConstantF[startRegister + i][1];
+ constantData[i * 4 + 2] = pixelShaderConstantF[startRegister + i][2];
+ constantData[i * 4 + 3] = pixelShaderConstantF[startRegister + i][3];
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetPixelShaderConstantI(unsigned int startRegister, int *constantData, unsigned int count)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ if(!constantData)
+ {
+ return INVALIDCALL();
+ }
+
+ for(unsigned int i = 0; i < count; i++)
+ {
+ constantData[i * 4 + 0] = pixelShaderConstantI[startRegister + i][0];
+ constantData[i * 4 + 1] = pixelShaderConstantI[startRegister + i][1];
+ constantData[i * 4 + 2] = pixelShaderConstantI[startRegister + i][2];
+ constantData[i * 4 + 3] = pixelShaderConstantI[startRegister + i][3];
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetRasterStatus(unsigned int index, D3DRASTER_STATUS *rasterStatus)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int swapChain = %d, D3DRASTER_STATUS *rasterStatus = 0x%0.8p", index, rasterStatus);
+
+ if(index >= GetNumberOfSwapChains())
+ {
+ return INVALIDCALL();
+ }
+
+ return swapChain->GetRasterStatus(rasterStatus);
+ }
+
+ long Direct3DDevice9::GetRenderState(D3DRENDERSTATETYPE state, unsigned long *value)
+ {
+ CriticalSection cs(this);
+
+ TRACE("D3DRENDERSTATETYPE state = %d, unsigned long *value = 0x%0.8p", state, value);
+
+ if(!value)
+ {
+ return INVALIDCALL();
+ }
+
+ *value = renderState[state];
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetRenderTarget(unsigned long index, IDirect3DSurface9 **renderTarget)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned long index = %d, IDirect3DSurface9 **renderTarget = 0x%0.8p", index, renderTarget);
+
+ if(index >= 4 || !renderTarget)
+ {
+ return INVALIDCALL();
+ }
+
+ *renderTarget = 0;
+
+ if(!this->renderTarget[index])
+ {
+ return NOTFOUND();
+ }
+
+ *renderTarget = this->renderTarget[index];
+ this->renderTarget[index]->AddRef();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetRenderTargetData(IDirect3DSurface9 *renderTarget, IDirect3DSurface9 *destSurface)
+ {
+ CriticalSection cs(this);
+
+ TRACE("IDirect3DSurface9 *renderTarget = 0x%0.8p, IDirect3DSurface9 *destSurface = 0x%0.8p", renderTarget, destSurface);
+
+ if(!renderTarget || !destSurface)
+ {
+ return INVALIDCALL();
+ }
+
+ D3DSURFACE_DESC sourceDescription;
+ D3DSURFACE_DESC destinationDescription;
+
+ renderTarget->GetDesc(&sourceDescription);
+ destSurface->GetDesc(&destinationDescription);
+
+ if(sourceDescription.Width != destinationDescription.Width ||
+ sourceDescription.Height != destinationDescription.Height ||
+ sourceDescription.Format != destinationDescription.Format ||
+ sourceDescription.MultiSampleType != D3DMULTISAMPLE_NONE)
+ {
+ return INVALIDCALL();
+ }
+
+ if(sourceDescription.Format == D3DFMT_A8R8G8B8 ||
+ sourceDescription.Format == D3DFMT_X8R8G8B8)
+ {
+ sw::Surface *source = static_cast<Direct3DSurface9*>(renderTarget);
+ sw::Surface *dest = static_cast<Direct3DSurface9*>(destSurface);
+
+ void *sourceBuffer = source->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
+ void *destBuffer = dest->lockExternal(0, 0, 0, sw::LOCK_WRITEONLY, sw::PUBLIC);
+
+ static void (__cdecl *blitFunction)(void *dst, void *src);
+ static sw::Routine *blitRoutine;
+ static sw::BlitState blitState = {0};
+
+ sw::BlitState update;
+ update.width = sourceDescription.Width;
+ update.height = sourceDescription.Height;
+ update.depth = 32;
+ update.stride = dest->getExternalPitchB();
+ update.HDR = false;
+ update.cursorHeight = 0;
+ update.cursorWidth = 0;
+
+ if(memcmp(&blitState, &update, sizeof(sw::BlitState)) != 0)
+ {
+ blitState = update;
+ delete blitRoutine;
+
+ blitRoutine = sw::FrameBuffer::copyRoutine(blitState);
+ blitFunction = (void(__cdecl*)(void*, void*))blitRoutine->getEntry();
+ }
+
+ blitFunction(destBuffer, sourceBuffer);
+
+ dest->unlockExternal();
+ source->unlockExternal();
+ }
+ else
+ {
+ return UpdateSurface(renderTarget, 0, destSurface, 0);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE state, unsigned long *value)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned long sampler = %d, D3DSAMPLERSTATETYPE type = %d, unsigned long *value = 0x%0.8p", sampler, state, value);
+
+ if(!value || state < D3DSAMP_ADDRESSU || state > D3DSAMP_DMAPOFFSET) // FIXME: Set *value to 0?
+ {
+ return INVALIDCALL();
+ }
+
+ if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
+ {
+ return INVALIDCALL();
+ }
+
+ if(sampler >= D3DVERTEXTEXTURESAMPLER0)
+ {
+ sampler = 16 + (sampler - D3DVERTEXTEXTURESAMPLER0);
+ }
+
+ *value = samplerState[sampler][state];
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetScissorRect(RECT *rect)
+ {
+ CriticalSection cs(this);
+
+ TRACE("RECT *rect = 0x%0.8p", rect);
+
+ if(!rect)
+ {
+ return INVALIDCALL();
+ }
+
+ *rect = scissorRect;
+
+ return D3D_OK;
+ }
+
+ int Direct3DDevice9::GetSoftwareVertexProcessing()
+ {
+ CriticalSection cs(this);
+
+ TRACE("void");
+
+ return softwareVertexProcessing ? TRUE : FALSE;
+ }
+
+ long Direct3DDevice9::GetStreamSource(unsigned int streamNumber, IDirect3DVertexBuffer9 **streamData, unsigned int *offset, unsigned int *stride)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int streamNumber = %d, IDirect3DVertexBuffer9 **streamData = 0x%0.8p, unsigned int *offset = 0x%0.8p, unsigned int *stride = 0x%0.8p", streamNumber, streamData, offset, stride);
+
+ if(streamNumber >= 16 || !streamData || !offset || !stride)
+ {
+ return INVALIDCALL();
+ }
+
+ *streamData = dataStream[streamNumber];
+
+ if(dataStream[streamNumber])
+ {
+ dataStream[streamNumber]->AddRef();
+ }
+
+ *offset = streamOffset[streamNumber];
+ *stride = streamStride[streamNumber];
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetStreamSourceFreq(unsigned int streamNumber, unsigned int *divider)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int streamNumber = %d, unsigned int *divider = 0x%0.8p", streamNumber, divider);
+
+ if(streamNumber >= 16 || !divider)
+ {
+ return INVALIDCALL();
+ }
+
+ *divider = streamSourceFreq[streamNumber];
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetSwapChain(unsigned int index, IDirect3DSwapChain9 **swapChain)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int index = %d, IDirect3DSwapChain9 **swapChain = 0x%0.8p", index, swapChain);
+
+ if(!swapChain || index >= GetNumberOfSwapChains())
+ {
+ return INVALIDCALL();
+ }
+
+ *swapChain = this->swapChain;
+
+ if(*swapChain)
+ {
+ (*swapChain)->AddRef();
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetTexture(unsigned long sampler, IDirect3DBaseTexture9 **texture)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned long sampler = %d, IDirect3DBaseTexture9 **texture = 0x%0.8p", sampler, texture);
+
+ if(!texture)
+ {
+ return INVALIDCALL();
+ }
+
+ *texture = 0;
+
+ if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
+ {
+ return INVALIDCALL();
+ }
+
+ *texture = this->texture[sampler];
+
+ if(this->texture[sampler])
+ {
+ this->texture[sampler]->AddRef();
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long *value)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned long stage = %d, D3DTEXTURESTAGESTATETYPE type = %d, unsigned long *value = 0x%0.8p", stage, type, value);
+
+ if(!value)
+ {
+ return INVALIDCALL();
+ }
+
+ *value = textureStageState[stage][type];
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetTransform(D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix)
+ {
+ CriticalSection cs(this);
+
+ TRACE("D3DTRANSFORMSTATETYPE state = %d, D3DMATRIX *matrix = 0x%0.8p", state, matrix);
+
+ if(!matrix || state < 0 || state > 511)
+ {
+ return INVALIDCALL();
+ }
+
+ *matrix = this->matrix[state];
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetVertexDeclaration(IDirect3DVertexDeclaration9 **declaration)
+ {
+ CriticalSection cs(this);
+
+ TRACE("IDirect3DVertexDeclaration9 **declaration = 0x%0.8p", declaration);
+
+ if(!declaration)
+ {
+ return INVALIDCALL();
+ }
+
+ *declaration = vertexDeclaration;
+
+ if(vertexDeclaration)
+ {
+ vertexDeclaration->AddRef();
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetVertexShader(IDirect3DVertexShader9 **shader)
+ {
+ CriticalSection cs(this);
+
+ TRACE("IDirect3DVertexShader9 **shader = 0x%0.8p", shader);
+
+ if(!shader)
+ {
+ return INVALIDCALL();
+ }
+
+ *shader = vertexShader;
+
+ if(vertexShader)
+ {
+ vertexShader->AddRef();
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetVertexShaderConstantB(unsigned int startRegister, int *constantData, unsigned int count)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ if(!constantData)
+ {
+ return INVALIDCALL();
+ }
+
+ for(unsigned int i = 0; i < count; i++)
+ {
+ constantData[i] = vertexShaderConstantB[startRegister + i];
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetVertexShaderConstantF(unsigned int startRegister, float *constantData, unsigned int count)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ if(!constantData)
+ {
+ return INVALIDCALL();
+ }
+
+ for(unsigned int i = 0; i < count; i++)
+ {
+ constantData[i * 4 + 0] = vertexShaderConstantF[startRegister + i][0];
+ constantData[i * 4 + 1] = vertexShaderConstantF[startRegister + i][1];
+ constantData[i * 4 + 2] = vertexShaderConstantF[startRegister + i][2];
+ constantData[i * 4 + 3] = vertexShaderConstantF[startRegister + i][3];
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetVertexShaderConstantI(unsigned int startRegister, int *constantData, unsigned int count)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ if(!constantData)
+ {
+ return INVALIDCALL();
+ }
+
+ for(unsigned int i = 0; i < count; i++)
+ {
+ constantData[i * 4 + 0] = vertexShaderConstantI[startRegister + i][0];
+ constantData[i * 4 + 1] = vertexShaderConstantI[startRegister + i][1];
+ constantData[i * 4 + 2] = vertexShaderConstantI[startRegister + i][2];
+ constantData[i * 4 + 3] = vertexShaderConstantI[startRegister + i][3];
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::GetViewport(D3DVIEWPORT9 *viewport)
+ {
+ CriticalSection cs(this);
+
+ TRACE("D3DVIEWPORT9 *viewport = 0x%0.8p", viewport);
+
+ if(!viewport)
+ {
+ return INVALIDCALL();
+ }
+
+ *viewport = this->viewport;
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::LightEnable(unsigned long index, int enable)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned long index = %d, int enable = %d", index, enable);
+
+ if(!light.exists(index)) // Insert default light
+ {
+ D3DLIGHT9 light;
+
+ light.Type = D3DLIGHT_DIRECTIONAL;
+ light.Diffuse.r = 1;
+ light.Diffuse.g = 1;
+ light.Diffuse.b = 1;
+ light.Diffuse.a = 0;
+ light.Specular.r = 0;
+ light.Specular.g = 0;
+ light.Specular.b = 0;
+ light.Specular.a = 0;
+ light.Ambient.r = 0;
+ light.Ambient.g = 0;
+ light.Ambient.b = 0;
+ light.Ambient.a = 0;
+ light.Position.x = 0;
+ light.Position.y = 0;
+ light.Position.z = 0;
+ light.Direction.x = 0;
+ light.Direction.y = 0;
+ light.Direction.z = 1;
+ light.Range = 0;
+ light.Falloff = 0;
+ light.Attenuation0 = 0;
+ light.Attenuation1 = 0;
+ light.Attenuation2 = 0;
+ light.Theta = 0;
+ light.Phi = 0;
+
+ this->light[index] = light;
+ this->light[index].enable = false;
+ }
+
+ if(!stateRecorder)
+ {
+ light[index].enable = (enable != FALSE);
+
+ lightsDirty = true;
+ }
+ else
+ {
+ stateRecorder->lightEnable(index, enable);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::MultiplyTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
+ {
+ CriticalSection cs(this);
+
+ TRACE("D3DTRANSFORMSTATETYPE state = %d, const D3DMATRIX *matrix = 0x%0.8p", state, matrix);
+
+ if(!matrix)
+ {
+ return INVALIDCALL();
+ }
+
+ D3DMATRIX *current = &this->matrix[state];
+
+ sw::Matrix C(current->_11, current->_21, current->_31, current->_41,
+ current->_12, current->_22, current->_32, current->_42,
+ current->_13, current->_23, current->_33, current->_43,
+ current->_14, current->_24, current->_34, current->_44);
+
+ sw::Matrix M(matrix->_11, matrix->_21, matrix->_31, matrix->_41,
+ matrix->_12, matrix->_22, matrix->_32, matrix->_42,
+ matrix->_13, matrix->_23, matrix->_33, matrix->_43,
+ matrix->_14, matrix->_24, matrix->_34, matrix->_44);
+
+ switch(state)
+ {
+ case D3DTS_WORLD:
+ renderer->setModelMatrix(C * M);
+ break;
+ case D3DTS_VIEW:
+ renderer->setViewMatrix(C * M);
+ break;
+ case D3DTS_PROJECTION:
+ renderer->setProjectionMatrix(C * M);
+ break;
+ case D3DTS_TEXTURE0:
+ renderer->setTextureMatrix(0, C * M);
+ break;
+ case D3DTS_TEXTURE1:
+ renderer->setTextureMatrix(1, C * M);
+ break;
+ case D3DTS_TEXTURE2:
+ renderer->setTextureMatrix(2, C * M);
+ break;
+ case D3DTS_TEXTURE3:
+ renderer->setTextureMatrix(3, C * M);
+ break;
+ case D3DTS_TEXTURE4:
+ renderer->setTextureMatrix(4, C * M);
+ break;
+ case D3DTS_TEXTURE5:
+ renderer->setTextureMatrix(5, C * M);
+ break;
+ case D3DTS_TEXTURE6:
+ renderer->setTextureMatrix(6, C * M);
+ break;
+ case D3DTS_TEXTURE7:
+ renderer->setTextureMatrix(7, C * M);
+ break;
+ default:
+ if(state > 256 && state < 512)
+ {
+ renderer->setModelMatrix(C * M, state - 256);
+ }
+ else ASSERT(false);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::Present(const RECT *sourceRect, const RECT *destRect, HWND destWindowOverride, const RGNDATA *dirtyRegion)
+ {
+ CriticalSection cs(this);
+
+ TRACE("const RECT *sourceRect = 0x%0.8p, const RECT *destRect = 0x%0.8p, HWND destWindowOverride = %d, const RGNDATA *dirtyRegion = 0x%0.8p", sourceRect, destRect, destWindowOverride, dirtyRegion);
+
+ return swapChain->Present(sourceRect, destRect, destWindowOverride, dirtyRegion, 0);
+ }
+
+ long Direct3DDevice9::ProcessVertices(unsigned int srcStartIndex, unsigned int destIndex, unsigned int vertexCount, IDirect3DVertexBuffer9 *destBuffer, IDirect3DVertexDeclaration9 *vertexDeclaration, unsigned long flags)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int srcStartIndex = %d, unsigned int destIndex = %d, unsigned int vertexCount = %d, IDirect3DVertexBuffer9 *destBuffer = 0x%0.8p, IDirect3DVertexDeclaration9 *vertexDeclaration = 0x%0.8p, unsigned long flags = %d", srcStartIndex, destIndex, vertexCount, destBuffer, vertexDeclaration, flags);
+
+ if(!destBuffer)
+ {
+ return INVALIDCALL();
+ }
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::Reset(D3DPRESENT_PARAMETERS *presentParameters)
+ {
+ CriticalSection cs(this);
+
+ TRACE("D3DPRESENT_PARAMETERS *presentParameters = 0x%0.8p", presentParameters);
+
+ if(!presentParameters)
+ {
+ return INVALIDCALL();
+ }
+
+ deviceWindow = presentParameters->hDeviceWindow;
+
+ if(depthStencil)
+ {
+ depthStencil->unbind();
+ depthStencil = 0;
+ }
+
+ if(autoDepthStencil)
+ {
+ autoDepthStencil->unbind();
+ autoDepthStencil = 0;
+ }
+
+ for(int index = 0; index < 4; index++)
+ {
+ if(renderTarget[index])
+ {
+ renderTarget[index]->unbind();
+ renderTarget[index] = 0;
+ }
+ }
+
+ if(!swapChain)
+ {
+ swapChain = new Direct3DSwapChain9(this, presentParameters);
+ swapChain->bind();
+ }
+ else
+ {
+ swapChain->reset(presentParameters);
+ }
+
+ if(presentParameters->EnableAutoDepthStencil != FALSE)
+ {
+ bool lockable = false;
+
+ switch(presentParameters->AutoDepthStencilFormat)
+ {
+ case D3DFMT_D15S1:
+ case D3DFMT_D24S8:
+ case D3DFMT_D24X8:
+ case D3DFMT_D24X4S4:
+ case D3DFMT_D24FS8:
+ case D3DFMT_D32:
+ case D3DFMT_D16:
+ case D3DFMT_DF24:
+ case D3DFMT_DF16:
+ case D3DFMT_INTZ:
+ lockable = false;
+ break;
+ case D3DFMT_S8_LOCKABLE:
+ case D3DFMT_D16_LOCKABLE:
+ case D3DFMT_D32F_LOCKABLE:
+ case D3DFMT_D32_LOCKABLE:
+ lockable = true;
+ break;
+ default:
+ ASSERT(false);
+ }
+
+ autoDepthStencil = new Direct3DSurface9(this, this, presentParameters->BackBufferWidth, presentParameters->BackBufferHeight, presentParameters->AutoDepthStencilFormat, D3DPOOL_DEFAULT, presentParameters->MultiSampleType, presentParameters->MultiSampleQuality, lockable, D3DUSAGE_DEPTHSTENCIL);
+ autoDepthStencil->bind();
+
+ SetDepthStencilSurface(autoDepthStencil);
+ }
+
+ IDirect3DSurface9 *renderTarget;
+ swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &renderTarget);
+ SetRenderTarget(0, renderTarget);
+ renderTarget->Release();
+
+ SetRenderTarget(1, 0);
+ SetRenderTarget(2, 0);
+ SetRenderTarget(3, 0);
+
+ softwareVertexProcessing = (behaviourFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) == D3DCREATE_SOFTWARE_VERTEXPROCESSING;
+
+ SetRenderState(D3DRS_ZENABLE, presentParameters->EnableAutoDepthStencil != FALSE ? D3DZB_TRUE : D3DZB_FALSE);
+ SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+ SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
+ SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
+ SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
+ SetRenderState(D3DRS_LASTPIXEL, TRUE);
+ SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
+ SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
+ SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
+ SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
+ SetRenderState(D3DRS_ALPHAREF, 0);
+ SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
+ SetRenderState(D3DRS_DITHERENABLE, FALSE);
+ SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ SetRenderState(D3DRS_FOGENABLE, FALSE);
+ SetRenderState(D3DRS_SPECULARENABLE, FALSE);
+ // SetRenderState(D3DRS_ZVISIBLE, 0);
+ SetRenderState(D3DRS_FOGCOLOR, 0);
+ SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
+ SetRenderState(D3DRS_FOGSTART, FtoDW(0.0f));
+ SetRenderState(D3DRS_FOGEND, FtoDW(1.0f));
+ SetRenderState(D3DRS_FOGDENSITY, FtoDW(1.0f));
+ SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
+ SetRenderState(D3DRS_STENCILENABLE, FALSE);
+ SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
+ SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
+ SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
+ SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
+ SetRenderState(D3DRS_STENCILREF, 0);
+ SetRenderState(D3DRS_STENCILMASK, 0xFFFFFFFF);
+ SetRenderState(D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
+ SetRenderState(D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
+ SetRenderState(D3DRS_WRAP0, 0);
+ SetRenderState(D3DRS_WRAP1, 0);
+ SetRenderState(D3DRS_WRAP2, 0);
+ SetRenderState(D3DRS_WRAP3, 0);
+ SetRenderState(D3DRS_WRAP4, 0);
+ SetRenderState(D3DRS_WRAP5, 0);
+ SetRenderState(D3DRS_WRAP6, 0);
+ SetRenderState(D3DRS_WRAP7, 0);
+ SetRenderState(D3DRS_CLIPPING, TRUE);
+ SetRenderState(D3DRS_LIGHTING, TRUE);
+ SetRenderState(D3DRS_AMBIENT, 0);
+ SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
+ SetRenderState(D3DRS_COLORVERTEX, TRUE);
+ SetRenderState(D3DRS_LOCALVIEWER, TRUE);
+ SetRenderState(D3DRS_NORMALIZENORMALS, FALSE);
+ SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
+ SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
+ SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
+ SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
+ SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
+ SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
+ SetRenderState(D3DRS_POINTSIZE, FtoDW(1.0f));
+ SetRenderState(D3DRS_POINTSIZE_MIN, FtoDW(1.0f));
+ SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
+ SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);
+ SetRenderState(D3DRS_POINTSCALE_A, FtoDW(1.0f));
+ SetRenderState(D3DRS_POINTSCALE_B, FtoDW(0.0f));
+ SetRenderState(D3DRS_POINTSCALE_C, FtoDW(0.0f));
+ SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
+ SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
+ SetRenderState(D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE);
+ SetRenderState(D3DRS_DEBUGMONITORTOKEN, D3DDMT_ENABLE);
+ SetRenderState(D3DRS_POINTSIZE_MAX, FtoDW(64.0f));
+ SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
+ SetRenderState(D3DRS_COLORWRITEENABLE, 0x0000000F);
+ SetRenderState(D3DRS_TWEENFACTOR, FtoDW(0.0f));
+ SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
+ SetRenderState(D3DRS_POSITIONDEGREE, D3DDEGREE_CUBIC);
+ SetRenderState(D3DRS_NORMALDEGREE, D3DDEGREE_LINEAR);
+ SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
+ SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, FtoDW(0.0f));
+ SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, FALSE);
+ SetRenderState(D3DRS_MINTESSELLATIONLEVEL, FtoDW(1.0f));
+ SetRenderState(D3DRS_MAXTESSELLATIONLEVEL, FtoDW(1.0f));
+ SetRenderState(D3DRS_ADAPTIVETESS_X, FtoDW(0.0f));
+ SetRenderState(D3DRS_ADAPTIVETESS_Y, FtoDW(0.0f));
+ SetRenderState(D3DRS_ADAPTIVETESS_Z, FtoDW(1.0f));
+ SetRenderState(D3DRS_ADAPTIVETESS_W, FtoDW(0.0f));
+ SetRenderState(D3DRS_ENABLEADAPTIVETESSELLATION, FALSE);
+ SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE);
+ SetRenderState(D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_KEEP);
+ SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_KEEP);
+ SetRenderState(D3DRS_CCW_STENCILPASS, D3DSTENCILOP_KEEP);
+ SetRenderState(D3DRS_CCW_STENCILFUNC, D3DCMP_ALWAYS);
+ SetRenderState(D3DRS_COLORWRITEENABLE1, 0x0000000F);
+ SetRenderState(D3DRS_COLORWRITEENABLE2, 0x0000000F);
+ SetRenderState(D3DRS_COLORWRITEENABLE3, 0x0000000F);
+ SetRenderState(D3DRS_BLENDFACTOR, 0xFFFFFFFF);
+ SetRenderState(D3DRS_SRGBWRITEENABLE, 0);
+ SetRenderState(D3DRS_DEPTHBIAS, FtoDW(0.0f));
+ SetRenderState(D3DRS_WRAP8, 0);
+ SetRenderState(D3DRS_WRAP9, 0);
+ SetRenderState(D3DRS_WRAP10, 0);
+ SetRenderState(D3DRS_WRAP11, 0);
+ SetRenderState(D3DRS_WRAP12, 0);
+ SetRenderState(D3DRS_WRAP13, 0);
+ SetRenderState(D3DRS_WRAP14, 0);
+ SetRenderState(D3DRS_WRAP15, 0);
+ SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
+ SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
+ SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ZERO);
+ SetRenderState(D3DRS_BLENDOPALPHA, D3DBLENDOP_ADD);
+
+ for(int i = 0; i < 8; i++)
+ {
+ SetTextureStageState(i, D3DTSS_COLOROP, i == 0 ? D3DTOP_MODULATE : D3DTOP_DISABLE);
+ SetTextureStageState(i, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ SetTextureStageState(i, D3DTSS_COLORARG2, D3DTA_CURRENT);
+ SetTextureStageState(i, D3DTSS_ALPHAOP, i == 0 ? D3DTOP_SELECTARG1 : D3DTOP_DISABLE);
+ SetTextureStageState(i, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ SetTextureStageState(i, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
+ SetTextureStageState(i, D3DTSS_BUMPENVMAT00, FtoDW(0.0f));
+ SetTextureStageState(i, D3DTSS_BUMPENVMAT01, FtoDW(0.0f));
+ SetTextureStageState(i, D3DTSS_BUMPENVMAT10, FtoDW(0.0f));
+ SetTextureStageState(i, D3DTSS_BUMPENVMAT11, FtoDW(0.0f));
+ SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, i);
+ SetTextureStageState(i, D3DTSS_BUMPENVLSCALE, FtoDW(0.0f));
+ SetTextureStageState(i, D3DTSS_BUMPENVLOFFSET, FtoDW(0.0f));
+ SetTextureStageState(i, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
+ SetTextureStageState(i, D3DTSS_COLORARG0, D3DTA_CURRENT);
+ SetTextureStageState(i, D3DTSS_ALPHAARG0, D3DTA_CURRENT);
+ SetTextureStageState(i, D3DTSS_RESULTARG, D3DTA_CURRENT);
+ SetTextureStageState(i, D3DTSS_CONSTANT, 0x00000000);
+ }
+
+ for(int i = 0; i <= D3DVERTEXTEXTURESAMPLER3; i = (i != 15) ? (i + 1) : D3DVERTEXTEXTURESAMPLER0)
+ {
+ SetTexture(i, 0);
+
+ SetSamplerState(i, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
+ SetSamplerState(i, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
+ SetSamplerState(i, D3DSAMP_ADDRESSW, D3DTADDRESS_WRAP);
+ SetSamplerState(i, D3DSAMP_BORDERCOLOR, 0x00000000);
+ SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
+ SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
+ SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
+ SetSamplerState(i, D3DSAMP_MIPMAPLODBIAS, 0);
+ SetSamplerState(i, D3DSAMP_MAXMIPLEVEL, 0);
+ SetSamplerState(i, D3DSAMP_MAXANISOTROPY, 1);
+ SetSamplerState(i, D3DSAMP_SRGBTEXTURE, 0);
+ SetSamplerState(i, D3DSAMP_ELEMENTINDEX, 0);
+ SetSamplerState(i, D3DSAMP_DMAPOFFSET, 0);
+ }
+
+ for(int i = 0; i < 6; i++)
+ {
+ float plane[4] = {0, 0, 0, 0};
+
+ SetClipPlane(i, plane);
+ }
+
+ currentPalette = 0xFFFF;
+
+ ShowCursor(FALSE);
+ delete cursor;
+ cursor = 0;
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetClipPlane(unsigned long index, const float *plane)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned long index = %d, const float *plane = 0x%0.8p", index, plane);
+
+ if(!plane || index >= 6)
+ {
+ return INVALIDCALL();
+ }
+
+ if(!stateRecorder)
+ {
+ this->plane[index][0] = plane[0];
+ this->plane[index][1] = plane[1];
+ this->plane[index][2] = plane[2];
+ this->plane[index][3] = plane[3];
+
+ renderer->setClipPlane(index, plane);
+ }
+ else
+ {
+ stateRecorder->setClipPlane(index, plane);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetClipStatus(const D3DCLIPSTATUS9 *clipStatus)
+ {
+ CriticalSection cs(this);
+
+ TRACE("const D3DCLIPSTATUS9 *clipStatus = 0x%0.8p", clipStatus);
+
+ if(!clipStatus)
+ {
+ return INVALIDCALL();
+ }
+
+ this->clipStatus = *clipStatus;
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetCurrentTexturePalette(unsigned int paletteNumber)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int paletteNumber = %d", paletteNumber);
+
+ if(paletteNumber > 0xFFFF || palette.find(paletteNumber) == palette.end())
+ {
+ return INVALIDCALL();
+ }
+
+ if(!stateRecorder)
+ {
+ currentPalette = paletteNumber;
+
+ sw::Surface::setTexturePalette((unsigned int*)&palette[currentPalette]);
+ }
+ else
+ {
+ stateRecorder->setCurrentTexturePalette(paletteNumber);
+ }
+
+ return D3D_OK;
+ }
+
+ void Direct3DDevice9::SetCursorPosition(int x, int y, unsigned long flags)
+ {
+ CriticalSection cs(this);
+
+ TRACE("int x = %d, int y = %d, unsigned long flags = 0x%0.8X", x, y, flags);
+
+ POINT point = {x, y};
+ HWND window = deviceWindow ? deviceWindow : focusWindow;
+ ScreenToClient(window, &point);
+
+ sw::FrameBuffer::setCursorPosition(point.x, point.y);
+ }
+
+ long Direct3DDevice9::SetCursorProperties(unsigned int x0, unsigned int y0, IDirect3DSurface9 *cursorBitmap)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int x0 = %d, unsigned int y0 = %d, IDirect3DSurface9 *cursorBitmap = 0x%0.8p", x0, y0, cursorBitmap);
+
+ if(!cursorBitmap)
+ {
+ return INVALIDCALL();
+ }
+
+ sw::Surface *cursorSurface = static_cast<Direct3DSurface9*>(cursorBitmap);
+
+ int width = cursorSurface->getExternalWidth();
+ int height = cursorSurface->getExternalHeight();
+ void *bitmap = cursorSurface->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
+
+ delete cursor;
+ cursor = new sw::Surface(0, width, height, 1, sw::FORMAT_A8R8G8B8, false, false);
+
+ void *buffer = cursor->lockExternal(0, 0, 0, sw::LOCK_DISCARD, sw::PUBLIC);
+ memcpy(buffer, bitmap, width * height * sizeof(unsigned int));
+ cursor->unlockExternal();
+
+ cursorSurface->unlockExternal();
+
+ if(showCursor)
+ {
+ sw::FrameBuffer::setCursorImage(cursor);
+ }
+ else
+ {
+ sw::FrameBuffer::setCursorImage(0);
+ }
+
+ sw::FrameBuffer::setCursorOrigin(x0, y0);
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetDepthStencilSurface(IDirect3DSurface9 *iDepthStencil)
+ {
+ CriticalSection cs(this);
+
+ TRACE("IDirect3DSurface9 *newDepthStencil = 0x%0.8p", iDepthStencil);
+
+ Direct3DSurface9 *depthStencil = static_cast<Direct3DSurface9*>(iDepthStencil);
+
+ if(this->depthStencil == depthStencil)
+ {
+ return D3D_OK;
+ }
+
+ if(depthStencil)
+ {
+ depthStencil->bind();
+ }
+
+ if(this->depthStencil)
+ {
+ this->depthStencil->unbind();
+ }
+
+ this->depthStencil = depthStencil;
+
+ renderer->setDepthStencil(depthStencil);
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetDialogBoxMode(int enableDialogs)
+ {
+ CriticalSection cs(this);
+
+ TRACE("int enableDialogs = %d", enableDialogs);
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetFVF(unsigned long FVF)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned long FVF = 0x%0.8X", FVF);
+
+ if(!stateRecorder)
+ {
+ if(FVF != 0 || !this->vertexDeclaration)
+ {
+ Direct3DVertexDeclaration9 *vertexDeclaration = new Direct3DVertexDeclaration9(this, FVF);
+ vertexDeclaration->bind();
+
+ if(this->vertexDeclaration)
+ {
+ this->vertexDeclaration->unbind();
+ }
+
+ this->vertexDeclaration = vertexDeclaration;
+ }
+ }
+ else
+ {
+ stateRecorder->setFVF(FVF);
+ }
+
+ return D3D_OK;
+ }
+
+ void Direct3DDevice9::SetGammaRamp(unsigned int index, unsigned long flags, const D3DGAMMARAMP *ramp)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int index = %d, unsigned long flags = 0x%0.8X, const D3DGAMMARAMP *ramp = 0x%0.8p", index, flags, ramp);
+
+ if(!ramp || index >= GetNumberOfSwapChains())
+ {
+ return;
+ }
+
+ swapChain->setGammaRamp((sw::GammaRamp*)ramp, flags & D3DSGR_CALIBRATE);
+ }
+
+ long Direct3DDevice9::SetIndices(IDirect3DIndexBuffer9* iIndexBuffer)
+ {
+ CriticalSection cs(this);
+
+ TRACE("IDirect3DIndexBuffer9* indexData = 0x%0.8p", iIndexBuffer);
+
+ Direct3DIndexBuffer9 *indexBuffer = static_cast<Direct3DIndexBuffer9*>(iIndexBuffer);
+
+ if(!stateRecorder)
+ {
+ if(this->indexData == indexBuffer)
+ {
+ return D3D_OK;
+ }
+
+ if(indexBuffer)
+ {
+ indexBuffer->bind();
+ }
+
+ if(this->indexData)
+ {
+ this->indexData->unbind();
+ }
+
+ this->indexData = indexBuffer;
+ }
+ else
+ {
+ stateRecorder->setIndices(indexBuffer);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetLight(unsigned long index, const D3DLIGHT9 *light)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned long index = %d, const D3DLIGHT9 *light = 0x%0.8p", index, light);
+
+ if(!light)
+ {
+ return INVALIDCALL();
+ }
+
+ if(!stateRecorder)
+ {
+ this->light[index] = *light;
+
+ lightsDirty = true;
+ }
+ else
+ {
+ stateRecorder->setLight(index, light);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetMaterial(const D3DMATERIAL9 *material)
+ {
+ CriticalSection cs(this);
+
+ TRACE("const D3DMATERIAL9 *material = 0x%0.8p", material);
+
+ if(!material)
+ {
+ return INVALIDCALL(); // FIXME: Correct behaviour?
+ }
+
+ if(!stateRecorder)
+ {
+ this->material = *material;
+
+ renderer->setMaterialAmbient(sw::Color<float>(material->Ambient.r, material->Ambient.g, material->Ambient.b, material->Ambient.a));
+ renderer->setMaterialDiffuse(sw::Color<float>(material->Diffuse.r, material->Diffuse.g, material->Diffuse.b, material->Diffuse.a));
+ renderer->setMaterialEmission(sw::Color<float>(material->Emissive.r, material->Emissive.g, material->Emissive.b, material->Emissive.a));
+ renderer->setMaterialShininess(material->Power);
+ renderer->setMaterialSpecular(sw::Color<float>(material->Specular.r, material->Specular.g, material->Specular.b, material->Specular.a));
+ }
+ else
+ {
+ stateRecorder->setMaterial(material);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetNPatchMode(float segments)
+ {
+ CriticalSection cs(this);
+
+ TRACE("float segments = %f", segments);
+
+ if(!stateRecorder)
+ {
+ if(segments < 1)
+ {
+ // NOTE: Disable
+ }
+ else
+ {
+ UNIMPLEMENTED();
+ }
+ }
+ else
+ {
+ stateRecorder->setNPatchMode(segments);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetPaletteEntries(unsigned int paletteNumber, const PALETTEENTRY *entries)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int paletteNumber = %d, const PALETTEENTRY *entries = 0x%0.8p", paletteNumber, entries);
+
+ if(paletteNumber > 0xFFFF || !entries)
+ {
+ return INVALIDCALL();
+ }
+
+ for(int i = 0; i < 256; i++)
+ {
+ palette[paletteNumber].entry[i] = entries[i];
+ }
+
+ if(paletteNumber == currentPalette)
+ {
+ sw::Surface::setTexturePalette((unsigned int*)&palette[currentPalette]);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetPixelShader(IDirect3DPixelShader9 *iPixelShader)
+ {
+ CriticalSection cs(this);
+
+ TRACE("IDirect3DPixelShader9 *shader = 0x%0.8p", iPixelShader);
+
+ Direct3DPixelShader9 *pixelShader = static_cast<Direct3DPixelShader9*>(iPixelShader);
+
+ if(!stateRecorder)
+ {
+ if(this->pixelShader == pixelShader)
+ {
+ return D3D_OK;
+ }
+
+ if(pixelShader)
+ {
+ pixelShader->bind();
+ }
+
+ if(this->pixelShader)
+ {
+ this->pixelShader->unbind();
+ }
+
+ this->pixelShader = pixelShader;
+ pixelShaderDirty = true;
+ }
+ else
+ {
+ stateRecorder->setPixelShader(pixelShader);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetPixelShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ if(!stateRecorder)
+ {
+ for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
+ {
+ pixelShaderConstantB[startRegister + i] = constantData[i];
+ }
+
+ pixelShaderConstantsBDirty = sw::max(startRegister + count, pixelShaderConstantsBDirty);
+ pixelShaderDirty = true; // Reload DEF constants
+ }
+ else
+ {
+ stateRecorder->setPixelShaderConstantB(startRegister, constantData, count);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ if(!stateRecorder)
+ {
+ for(unsigned int i = 0; i < count && startRegister + i < 224; i++)
+ {
+ pixelShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0];
+ pixelShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1];
+ pixelShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2];
+ pixelShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3];
+ }
+
+ pixelShaderConstantsFDirty = sw::max(startRegister + count, pixelShaderConstantsFDirty);
+ pixelShaderDirty = true; // Reload DEF constants
+ }
+ else
+ {
+ stateRecorder->setPixelShaderConstantF(startRegister, constantData, count);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetPixelShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ if(!stateRecorder)
+ {
+ for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
+ {
+ pixelShaderConstantI[startRegister + i][0] = constantData[i * 4 + 0];
+ pixelShaderConstantI[startRegister + i][1] = constantData[i * 4 + 1];
+ pixelShaderConstantI[startRegister + i][2] = constantData[i * 4 + 2];
+ pixelShaderConstantI[startRegister + i][3] = constantData[i * 4 + 3];
+ }
+
+ pixelShaderConstantsIDirty = sw::max(startRegister + count, pixelShaderConstantsIDirty);
+ pixelShaderDirty = true; // Reload DEF constants
+ }
+ else
+ {
+ stateRecorder->setPixelShaderConstantI(startRegister, constantData, count);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetRenderState(D3DRENDERSTATETYPE state, unsigned long value)
+ {
+ CriticalSection cs(this);
+
+ TRACE("D3DRENDERSTATETYPE state = %d, unsigned long value = %d", state, value);
+
+ if(state < D3DRS_ZENABLE || state > D3DRS_BLENDOPALPHA)
+ {
+ return D3D_OK; // FIXME: Warning
+ }
+
+ if(!stateRecorder)
+ {
+ if(!init && renderState[state] == value)
+ {
+ return D3D_OK;
+ }
+
+ renderState[state] = value;
+
+ switch(state)
+ {
+ case D3DRS_ZENABLE:
+ switch(value)
+ {
+ case D3DZB_TRUE:
+ case D3DZB_USEW:
+ renderer->setDepthBufferEnable(true);
+ break;
+ case D3DZB_FALSE:
+ renderer->setDepthBufferEnable(false);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_FILLMODE:
+ switch(value)
+ {
+ case D3DFILL_POINT:
+ renderer->setFillMode(sw::Context::FILL_VERTEX);
+ break;
+ case D3DFILL_WIREFRAME:
+ renderer->setFillMode(sw::Context::FILL_WIREFRAME);
+ break;
+ case D3DFILL_SOLID:
+ renderer->setFillMode(sw::Context::FILL_SOLID);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_SHADEMODE:
+ switch(value)
+ {
+ case D3DSHADE_FLAT:
+ renderer->setShadingMode(sw::Context::SHADING_FLAT);
+ break;
+ case D3DSHADE_GOURAUD:
+ renderer->setShadingMode(sw::Context::SHADING_GOURAUD);
+ break;
+ case D3DSHADE_PHONG:
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_ZWRITEENABLE:
+ renderer->setDepthWriteEnable(value != FALSE);
+ break;
+ case D3DRS_ALPHATESTENABLE:
+ renderer->setAlphaTestEnable(value != FALSE);
+ break;
+ case D3DRS_LASTPIXEL:
+ // if(!init) UNIMPLEMENTED(); // FIXME
+ break;
+ case D3DRS_SRCBLEND:
+ switch(value)
+ {
+ case D3DBLEND_ZERO:
+ renderer->setSourceBlendFactor(sw::Context::BLEND_ZERO);
+ break;
+ case D3DBLEND_ONE:
+ renderer->setSourceBlendFactor(sw::Context::BLEND_ONE);
+ break;
+ case D3DBLEND_SRCCOLOR:
+ renderer->setSourceBlendFactor(sw::Context::BLEND_SOURCE);
+ break;
+ case D3DBLEND_INVSRCCOLOR:
+ renderer->setSourceBlendFactor(sw::Context::BLEND_INVSOURCE);
+ break;
+ case D3DBLEND_SRCALPHA:
+ renderer->setSourceBlendFactor(sw::Context::BLEND_SOURCEALPHA);
+ break;
+ case D3DBLEND_INVSRCALPHA:
+ renderer->setSourceBlendFactor(sw::Context::BLEND_INVSOURCEALPHA);
+ break;
+ case D3DBLEND_DESTALPHA:
+ renderer->setSourceBlendFactor(sw::Context::BLEND_DESTALPHA);
+ break;
+ case D3DBLEND_INVDESTALPHA:
+ renderer->setSourceBlendFactor(sw::Context::BLEND_INVDESTALPHA);
+ break;
+ case D3DBLEND_DESTCOLOR:
+ renderer->setSourceBlendFactor(sw::Context::BLEND_DEST);
+ break;
+ case D3DBLEND_INVDESTCOLOR:
+ renderer->setSourceBlendFactor(sw::Context::BLEND_INVDEST);
+ break;
+ case D3DBLEND_SRCALPHASAT:
+ renderer->setSourceBlendFactor(sw::Context::BLEND_SRCALPHASAT);
+ break;
+ case D3DBLEND_BOTHSRCALPHA:
+ renderer->setSourceBlendFactor(sw::Context::BLEND_SOURCEALPHA);
+ renderer->setDestBlendFactor(sw::Context::BLEND_INVSOURCEALPHA);
+ break;
+ case D3DBLEND_BOTHINVSRCALPHA:
+ renderer->setSourceBlendFactor(sw::Context::BLEND_INVSOURCEALPHA);
+ renderer->setDestBlendFactor(sw::Context::BLEND_SOURCEALPHA);
+ break;
+ case D3DBLEND_BLENDFACTOR:
+ renderer->setSourceBlendFactor(sw::Context::BLEND_CONSTANT);
+ break;
+ case D3DBLEND_INVBLENDFACTOR:
+ renderer->setSourceBlendFactor(sw::Context::BLEND_INVCONSTANT);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_DESTBLEND:
+ switch(value)
+ {
+ case D3DBLEND_ZERO:
+ renderer->setDestBlendFactor(sw::Context::BLEND_ZERO);
+ break;
+ case D3DBLEND_ONE:
+ renderer->setDestBlendFactor(sw::Context::BLEND_ONE);
+ break;
+ case D3DBLEND_SRCCOLOR:
+ renderer->setDestBlendFactor(sw::Context::BLEND_SOURCE);
+ break;
+ case D3DBLEND_INVSRCCOLOR:
+ renderer->setDestBlendFactor(sw::Context::BLEND_INVSOURCE);
+ break;
+ case D3DBLEND_SRCALPHA:
+ renderer->setDestBlendFactor(sw::Context::BLEND_SOURCEALPHA);
+ break;
+ case D3DBLEND_INVSRCALPHA:
+ renderer->setDestBlendFactor(sw::Context::BLEND_INVSOURCEALPHA);
+ break;
+ case D3DBLEND_DESTALPHA:
+ renderer->setDestBlendFactor(sw::Context::BLEND_DESTALPHA);
+ break;
+ case D3DBLEND_INVDESTALPHA:
+ renderer->setDestBlendFactor(sw::Context::BLEND_INVDESTALPHA);
+ break;
+ case D3DBLEND_DESTCOLOR:
+ renderer->setDestBlendFactor(sw::Context::BLEND_DEST);
+ break;
+ case D3DBLEND_INVDESTCOLOR:
+ renderer->setDestBlendFactor(sw::Context::BLEND_INVDEST);
+ break;
+ case D3DBLEND_SRCALPHASAT:
+ renderer->setDestBlendFactor(sw::Context::BLEND_SRCALPHASAT);
+ break;
+ case D3DBLEND_BOTHSRCALPHA:
+ renderer->setSourceBlendFactor(sw::Context::BLEND_SOURCEALPHA);
+ renderer->setDestBlendFactor(sw::Context::BLEND_INVSOURCEALPHA);
+ break;
+ case D3DBLEND_BOTHINVSRCALPHA:
+ renderer->setSourceBlendFactor(sw::Context::BLEND_INVSOURCEALPHA);
+ renderer->setDestBlendFactor(sw::Context::BLEND_SOURCEALPHA);
+ break;
+ case D3DBLEND_BLENDFACTOR:
+ renderer->setDestBlendFactor(sw::Context::BLEND_CONSTANT);
+ break;
+ case D3DBLEND_INVBLENDFACTOR:
+ renderer->setDestBlendFactor(sw::Context::BLEND_INVCONSTANT);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_CULLMODE:
+ switch(value)
+ {
+ case D3DCULL_NONE:
+ renderer->setCullMode(sw::Context::CULL_NONE);
+ break;
+ case D3DCULL_CCW:
+ renderer->setCullMode(sw::Context::CULL_COUNTERCLOCKWISE);
+ break;
+ case D3DCULL_CW:
+ renderer->setCullMode(sw::Context::CULL_CLOCKWISE);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_ZFUNC:
+ switch(value)
+ {
+ case D3DCMP_NEVER:
+ renderer->setDepthCompare(sw::Context::DEPTH_NEVER);
+ break;
+ case D3DCMP_LESS:
+ renderer->setDepthCompare(sw::Context::DEPTH_LESS);
+ break;
+ case D3DCMP_EQUAL:
+ renderer->setDepthCompare(sw::Context::DEPTH_EQUAL);
+ break;
+ case D3DCMP_LESSEQUAL:
+ renderer->setDepthCompare(sw::Context::DEPTH_LESSEQUAL);
+ break;
+ case D3DCMP_GREATER:
+ renderer->setDepthCompare(sw::Context::DEPTH_GREATER);
+ break;
+ case D3DCMP_NOTEQUAL:
+ renderer->setDepthCompare(sw::Context::DEPTH_NOTEQUAL);
+ break;
+ case D3DCMP_GREATEREQUAL:
+ renderer->setDepthCompare(sw::Context::DEPTH_GREATEREQUAL);
+ break;
+ case D3DCMP_ALWAYS:
+ renderer->setDepthCompare(sw::Context::DEPTH_ALWAYS);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_ALPHAREF:
+ renderer->setAlphaReference(value & 0x000000FF);
+ break;
+ case D3DRS_ALPHAFUNC:
+ switch(value)
+ {
+ case D3DCMP_NEVER:
+ renderer->setAlphaCompare(sw::Context::ALPHA_NEVER);
+ break;
+ case D3DCMP_LESS:
+ renderer->setAlphaCompare(sw::Context::ALPHA_LESS);
+ break;
+ case D3DCMP_EQUAL:
+ renderer->setAlphaCompare(sw::Context::ALPHA_EQUAL);
+ break;
+ case D3DCMP_LESSEQUAL:
+ renderer->setAlphaCompare(sw::Context::ALPHA_LESSEQUAL);
+ break;
+ case D3DCMP_GREATER:
+ renderer->setAlphaCompare(sw::Context::ALPHA_GREATER);
+ break;
+ case D3DCMP_NOTEQUAL:
+ renderer->setAlphaCompare(sw::Context::ALPHA_NOTEQUAL);
+ break;
+ case D3DCMP_GREATEREQUAL:
+ renderer->setAlphaCompare(sw::Context::ALPHA_GREATEREQUAL);
+ break;
+ case D3DCMP_ALWAYS:
+ renderer->setAlphaCompare(sw::Context::ALPHA_ALWAYS);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_DITHERENABLE:
+ // if(!init) UNIMPLEMENTED();
+ break;
+ case D3DRS_ALPHABLENDENABLE:
+ renderer->setAlphaBlendEnable(value != FALSE);
+ break;
+ case D3DRS_FOGENABLE:
+ renderer->setFogEnable(value != FALSE);
+ break;
+ case D3DRS_FOGCOLOR:
+ renderer->setFogColor(value);
+ break;
+ case D3DRS_FOGTABLEMODE:
+ switch(value)
+ {
+ case D3DFOG_NONE:
+ renderer->setPixelFogMode(sw::Context::FOG_NONE);
+ break;
+ case D3DFOG_LINEAR:
+ renderer->setPixelFogMode(sw::Context::FOG_LINEAR);
+ break;
+ case D3DFOG_EXP:
+ renderer->setPixelFogMode(sw::Context::FOG_EXP);
+ break;
+ case D3DFOG_EXP2:
+ renderer->setPixelFogMode(sw::Context::FOG_EXP2);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_FOGSTART:
+ renderer->setFogStart((float&)value);
+ break;
+ case D3DRS_FOGEND:
+ renderer->setFogEnd((float&)value);
+ break;
+ case D3DRS_FOGDENSITY:
+ renderer->setFogDensity((float&)value);
+ break;
+ case D3DRS_RANGEFOGENABLE:
+ renderer->setRangeFogEnable(value != FALSE);
+ break;
+ case D3DRS_SPECULARENABLE:
+ renderer->setSpecularEnable(value != FALSE);
+ break;
+ case D3DRS_STENCILENABLE:
+ renderer->setStencilEnable(value != FALSE);
+ break;
+ case D3DRS_STENCILFAIL:
+ switch(value)
+ {
+ case D3DSTENCILOP_KEEP:
+ renderer->setStencilFailOperation(sw::Context::OPERATION_KEEP);
+ break;
+ case D3DSTENCILOP_ZERO:
+ renderer->setStencilFailOperation(sw::Context::OPERATION_ZERO);
+ break;
+ case D3DSTENCILOP_REPLACE:
+ renderer->setStencilFailOperation(sw::Context::OPERATION_REPLACE);
+ break;
+ case D3DSTENCILOP_INCRSAT:
+ renderer->setStencilFailOperation(sw::Context::OPERATION_INCRSAT);
+ break;
+ case D3DSTENCILOP_DECRSAT:
+ renderer->setStencilFailOperation(sw::Context::OPERATION_DECRSAT);
+ break;
+ case D3DSTENCILOP_INVERT:
+ renderer->setStencilFailOperation(sw::Context::OPERATION_INVERT);
+ break;
+ case D3DSTENCILOP_INCR:
+ renderer->setStencilFailOperation(sw::Context::OPERATION_INCR);
+ break;
+ case D3DSTENCILOP_DECR:
+ renderer->setStencilFailOperation(sw::Context::OPERATION_DECR);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_STENCILZFAIL:
+ switch(value)
+ {
+ case D3DSTENCILOP_KEEP:
+ renderer->setStencilZFailOperation(sw::Context::OPERATION_KEEP);
+ break;
+ case D3DSTENCILOP_ZERO:
+ renderer->setStencilZFailOperation(sw::Context::OPERATION_ZERO);
+ break;
+ case D3DSTENCILOP_REPLACE:
+ renderer->setStencilZFailOperation(sw::Context::OPERATION_REPLACE);
+ break;
+ case D3DSTENCILOP_INCRSAT:
+ renderer->setStencilZFailOperation(sw::Context::OPERATION_INCRSAT);
+ break;
+ case D3DSTENCILOP_DECRSAT:
+ renderer->setStencilZFailOperation(sw::Context::OPERATION_DECRSAT);
+ break;
+ case D3DSTENCILOP_INVERT:
+ renderer->setStencilZFailOperation(sw::Context::OPERATION_INVERT);
+ break;
+ case D3DSTENCILOP_INCR:
+ renderer->setStencilZFailOperation(sw::Context::OPERATION_INCR);
+ break;
+ case D3DSTENCILOP_DECR:
+ renderer->setStencilZFailOperation(sw::Context::OPERATION_DECR);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_STENCILPASS:
+ switch(value)
+ {
+ case D3DSTENCILOP_KEEP:
+ renderer->setStencilPassOperation(sw::Context::OPERATION_KEEP);
+ break;
+ case D3DSTENCILOP_ZERO:
+ renderer->setStencilPassOperation(sw::Context::OPERATION_ZERO);
+ break;
+ case D3DSTENCILOP_REPLACE:
+ renderer->setStencilPassOperation(sw::Context::OPERATION_REPLACE);
+ break;
+ case D3DSTENCILOP_INCRSAT:
+ renderer->setStencilPassOperation(sw::Context::OPERATION_INCRSAT);
+ break;
+ case D3DSTENCILOP_DECRSAT:
+ renderer->setStencilPassOperation(sw::Context::OPERATION_DECRSAT);
+ break;
+ case D3DSTENCILOP_INVERT:
+ renderer->setStencilPassOperation(sw::Context::OPERATION_INVERT);
+ break;
+ case D3DSTENCILOP_INCR:
+ renderer->setStencilPassOperation(sw::Context::OPERATION_INCR);
+ break;
+ case D3DSTENCILOP_DECR:
+ renderer->setStencilPassOperation(sw::Context::OPERATION_DECR);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_STENCILFUNC:
+ switch(value)
+ {
+ case D3DCMP_NEVER:
+ renderer->setStencilCompare(sw::Context::STENCIL_NEVER);
+ break;
+ case D3DCMP_LESS:
+ renderer->setStencilCompare(sw::Context::STENCIL_LESS);
+ break;
+ case D3DCMP_EQUAL:
+ renderer->setStencilCompare(sw::Context::STENCIL_EQUAL);
+ break;
+ case D3DCMP_LESSEQUAL:
+ renderer->setStencilCompare(sw::Context::STENCIL_LESSEQUAL);
+ break;
+ case D3DCMP_GREATER:
+ renderer->setStencilCompare(sw::Context::STENCIL_GREATER);
+ break;
+ case D3DCMP_NOTEQUAL:
+ renderer->setStencilCompare(sw::Context::STENCIL_NOTEQUAL);
+ break;
+ case D3DCMP_GREATEREQUAL:
+ renderer->setStencilCompare(sw::Context::STENCIL_GREATEREQUAL);
+ break;
+ case D3DCMP_ALWAYS:
+ renderer->setStencilCompare(sw::Context::STENCIL_ALWAYS);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_STENCILREF:
+ renderer->setStencilReference(value);
+ renderer->setStencilReferenceCCW(value);
+ break;
+ case D3DRS_STENCILMASK:
+ renderer->setStencilMask(value);
+ renderer->setStencilMaskCCW(value);
+ break;
+ case D3DRS_STENCILWRITEMASK:
+ renderer->setStencilWriteMask(value);
+ renderer->setStencilWriteMaskCCW(value);
+ break;
+ case D3DRS_TEXTUREFACTOR:
+ renderer->setTextureFactor(value);
+ break;
+ case D3DRS_WRAP0:
+ renderer->setTextureWrap(0, value);
+ break;
+ case D3DRS_WRAP1:
+ renderer->setTextureWrap(1, value);
+ break;
+ case D3DRS_WRAP2:
+ renderer->setTextureWrap(2, value);
+ break;
+ case D3DRS_WRAP3:
+ renderer->setTextureWrap(3, value);
+ break;
+ case D3DRS_WRAP4:
+ renderer->setTextureWrap(4, value);
+ break;
+ case D3DRS_WRAP5:
+ renderer->setTextureWrap(5, value);
+ break;
+ case D3DRS_WRAP6:
+ renderer->setTextureWrap(6, value);
+ break;
+ case D3DRS_WRAP7:
+ renderer->setTextureWrap(7, value);
+ break;
+ case D3DRS_CLIPPING:
+ // Ignored, clipping is always performed
+ break;
+ case D3DRS_LIGHTING:
+ renderer->setLightingEnable(value != FALSE);
+ break;
+ case D3DRS_AMBIENT:
+ renderer->setGlobalAmbient(value);
+ break;
+ case D3DRS_FOGVERTEXMODE:
+ switch(value)
+ {
+ case D3DFOG_NONE:
+ renderer->setVertexFogMode(sw::Context::FOG_NONE);
+ break;
+ case D3DFOG_LINEAR:
+ renderer->setVertexFogMode(sw::Context::FOG_LINEAR);
+ break;
+ case D3DFOG_EXP:
+ renderer->setVertexFogMode(sw::Context::FOG_EXP);
+ break;
+ case D3DFOG_EXP2:
+ renderer->setVertexFogMode(sw::Context::FOG_EXP2);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_COLORVERTEX:
+ renderer->setColorVertexEnable(value != FALSE);
+ break;
+ case D3DRS_LOCALVIEWER:
+ renderer->setLocalViewer(value != FALSE);
+ break;
+ case D3DRS_NORMALIZENORMALS:
+ renderer->setNormalizeNormals(value != FALSE);
+ break;
+ case D3DRS_DIFFUSEMATERIALSOURCE:
+ switch(value)
+ {
+ case D3DMCS_MATERIAL:
+ renderer->setDiffuseMaterialSource(sw::Context::MATERIAL);
+ break;
+ case D3DMCS_COLOR1:
+ renderer->setDiffuseMaterialSource(sw::Context::COLOR1);
+ break;
+ case D3DMCS_COLOR2:
+ renderer->setDiffuseMaterialSource(sw::Context::COLOR2);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_SPECULARMATERIALSOURCE:
+ switch(value)
+ {
+ case D3DMCS_MATERIAL:
+ renderer->setSpecularMaterialSource(sw::Context::MATERIAL);
+ break;
+ case D3DMCS_COLOR1:
+ renderer->setSpecularMaterialSource(sw::Context::COLOR1);
+ break;
+ case D3DMCS_COLOR2:
+ renderer->setSpecularMaterialSource(sw::Context::COLOR2);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_AMBIENTMATERIALSOURCE:
+ switch(value)
+ {
+ case D3DMCS_MATERIAL:
+ renderer->setAmbientMaterialSource(sw::Context::MATERIAL);
+ break;
+ case D3DMCS_COLOR1:
+ renderer->setAmbientMaterialSource(sw::Context::COLOR1);
+ break;
+ case D3DMCS_COLOR2:
+ renderer->setAmbientMaterialSource(sw::Context::COLOR2);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_EMISSIVEMATERIALSOURCE:
+ switch(value)
+ {
+ case D3DMCS_MATERIAL:
+ renderer->setEmissiveMaterialSource(sw::Context::MATERIAL);
+ break;
+ case D3DMCS_COLOR1:
+ renderer->setEmissiveMaterialSource(sw::Context::COLOR1);
+ break;
+ case D3DMCS_COLOR2:
+ renderer->setEmissiveMaterialSource(sw::Context::COLOR2);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_VERTEXBLEND:
+ switch(value)
+ {
+ case D3DVBF_DISABLE:
+ renderer->setVertexBlendMatrixCount(0);
+ break;
+ case D3DVBF_1WEIGHTS:
+ renderer->setVertexBlendMatrixCount(2);
+ break;
+ case D3DVBF_2WEIGHTS:
+ renderer->setVertexBlendMatrixCount(3);
+ break;
+ case D3DVBF_3WEIGHTS:
+ renderer->setVertexBlendMatrixCount(4);
+ break;
+ case D3DVBF_TWEENING:
+ UNIMPLEMENTED();
+ break;
+ case D3DVBF_0WEIGHTS:
+ renderer->setVertexBlendMatrixCount(1);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_CLIPPLANEENABLE:
+ renderer->setClipFlags(value);
+ break;
+ case D3DRS_POINTSIZE:
+ if(value == D3DFMT_INST && pixelShaderVersionX >= D3DPS_VERSION(2, 0)) // ATI hack to enable instancing on SM 2.0 hardware
+ {
+ instancingEnabled = true;
+ }
+ else if(value == D3DFMT_A2M1) // ATI hack to enable transparency anti-aliasing
+ {
+ renderer->setTransparencyAntialiasing(sw::Context::TRANSPARENCY_ALPHA_TO_COVERAGE);
+ renderer->setAlphaTestEnable(true);
+ }
+ else if(value == D3DFMT_A2M0) // ATI hack to disable transparency anti-aliasing
+ {
+ renderer->setTransparencyAntialiasing(sw::Context::TRANSPARENCY_NONE);
+ renderer->setAlphaTestEnable(false);
+ }
+ else
+ {
+ renderer->setPointSize((float&)value);
+ }
+ break;
+ case D3DRS_POINTSIZE_MIN:
+ renderer->setPointSizeMin((float&)value);
+ break;
+ case D3DRS_POINTSPRITEENABLE:
+ renderer->setPointSpriteEnable(value != FALSE);
+ break;
+ case D3DRS_POINTSCALEENABLE:
+ renderer->setPointScaleEnable(value != FALSE);
+ break;
+ case D3DRS_POINTSCALE_A:
+ renderer->setPointScaleA((float&)value);
+ break;
+ case D3DRS_POINTSCALE_B:
+ renderer->setPointScaleB((float&)value);
+ break;
+ case D3DRS_POINTSCALE_C:
+ renderer->setPointScaleC((float&)value);
+ break;
+ case D3DRS_MULTISAMPLEANTIALIAS:
+ // if(!init) UNIMPLEMENTED();
+ break;
+ case D3DRS_MULTISAMPLEMASK:
+ SetRenderTarget(0, renderTarget[0]); // Sets the multi-sample mask, if maskable
+ break;
+ case D3DRS_PATCHEDGESTYLE:
+ if(!init) if(value != D3DPATCHEDGE_DISCRETE) UNIMPLEMENTED();
+ break;
+ case D3DRS_DEBUGMONITORTOKEN:
+ if(!init) UNIMPLEMENTED();
+ break;
+ case D3DRS_POINTSIZE_MAX:
+ renderer->setPointSizeMax((float&)value);
+ break;
+ case D3DRS_INDEXEDVERTEXBLENDENABLE:
+ renderer->setIndexedVertexBlendEnable(value != FALSE);
+ break;
+ case D3DRS_COLORWRITEENABLE:
+ renderer->setColorWriteMask(0, value & 0x0000000F);
+ break;
+ case D3DRS_TWEENFACTOR:
+ if(!init) UNIMPLEMENTED();
+ break;
+ case D3DRS_BLENDOP:
+ switch(value)
+ {
+ case D3DBLENDOP_ADD:
+ renderer->setBlendOperation(sw::Context::BLENDOP_ADD);
+ break;
+ case D3DBLENDOP_SUBTRACT:
+ renderer->setBlendOperation(sw::Context::BLENDOP_SUB);
+ break;
+ case D3DBLENDOP_REVSUBTRACT:
+ renderer->setBlendOperation(sw::Context::BLENDOP_INVSUB);
+ break;
+ case D3DBLENDOP_MIN:
+ renderer->setBlendOperation(sw::Context::BLENDOP_MIN);
+ break;
+ case D3DBLENDOP_MAX:
+ renderer->setBlendOperation(sw::Context::BLENDOP_MAX);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_POSITIONDEGREE:
+ if(!init) UNIMPLEMENTED();
+ break;
+ case D3DRS_NORMALDEGREE:
+ if(!init) UNIMPLEMENTED();
+ break;
+ case D3DRS_SCISSORTESTENABLE:
+ scissorEnable = (value != FALSE);
+ break;
+ case D3DRS_SLOPESCALEDEPTHBIAS:
+ renderer->setSlopeDepthBias((float&)value);
+ break;
+ case D3DRS_ANTIALIASEDLINEENABLE:
+ if(!init) if(value != FALSE) UNIMPLEMENTED();
+ break;
+ case D3DRS_MINTESSELLATIONLEVEL:
+ if(!init) UNIMPLEMENTED();
+ break;
+ case D3DRS_MAXTESSELLATIONLEVEL:
+ if(!init) UNIMPLEMENTED();
+ break;
+ case D3DRS_ADAPTIVETESS_X:
+ if(!init) if((float&)value != 0.0f) UNIMPLEMENTED();
+ break;
+ case D3DRS_ADAPTIVETESS_Y:
+ if(value == D3DFMT_ATOC) // NVIDIA hack to enable transparency anti-aliasing
+ {
+ renderer->setTransparencyAntialiasing(sw::Context::TRANSPARENCY_ALPHA_TO_COVERAGE);
+ }
+ else if(value == D3DFMT_UNKNOWN) // NVIDIA hack to disable transparency anti-aliasing
+ {
+ renderer->setTransparencyAntialiasing(sw::Context::TRANSPARENCY_NONE);
+ }
+ else
+ {
+ if(!init) if((float&)value != 0.0f) UNIMPLEMENTED();
+ }
+ break;
+ case D3DRS_ADAPTIVETESS_Z:
+ if(!init) if((float&)value != 1.0f) UNIMPLEMENTED();
+ break;
+ case D3DRS_ADAPTIVETESS_W:
+ if(!init) if((float&)value != 0.0f) UNIMPLEMENTED();
+ break;
+ case D3DRS_ENABLEADAPTIVETESSELLATION:
+ if(!init) UNIMPLEMENTED();
+ break;
+ case D3DRS_TWOSIDEDSTENCILMODE:
+ renderer->setTwoSidedStencil(value != FALSE);
+ break;
+ case D3DRS_CCW_STENCILFAIL:
+ switch(value)
+ {
+ case D3DSTENCILOP_KEEP:
+ renderer->setStencilFailOperationCCW(sw::Context::OPERATION_KEEP);
+ break;
+ case D3DSTENCILOP_ZERO:
+ renderer->setStencilFailOperationCCW(sw::Context::OPERATION_ZERO);
+ break;
+ case D3DSTENCILOP_REPLACE:
+ renderer->setStencilFailOperationCCW(sw::Context::OPERATION_REPLACE);
+ break;
+ case D3DSTENCILOP_INCRSAT:
+ renderer->setStencilFailOperationCCW(sw::Context::OPERATION_INCRSAT);
+ break;
+ case D3DSTENCILOP_DECRSAT:
+ renderer->setStencilFailOperationCCW(sw::Context::OPERATION_DECRSAT);
+ break;
+ case D3DSTENCILOP_INVERT:
+ renderer->setStencilFailOperationCCW(sw::Context::OPERATION_INVERT);
+ break;
+ case D3DSTENCILOP_INCR:
+ renderer->setStencilFailOperationCCW(sw::Context::OPERATION_INCR);
+ break;
+ case D3DSTENCILOP_DECR:
+ renderer->setStencilFailOperationCCW(sw::Context::OPERATION_DECR);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_CCW_STENCILZFAIL:
+ switch(value)
+ {
+ case D3DSTENCILOP_KEEP:
+ renderer->setStencilZFailOperationCCW(sw::Context::OPERATION_KEEP);
+ break;
+ case D3DSTENCILOP_ZERO:
+ renderer->setStencilZFailOperationCCW(sw::Context::OPERATION_ZERO);
+ break;
+ case D3DSTENCILOP_REPLACE:
+ renderer->setStencilZFailOperationCCW(sw::Context::OPERATION_REPLACE);
+ break;
+ case D3DSTENCILOP_INCRSAT:
+ renderer->setStencilZFailOperationCCW(sw::Context::OPERATION_INCRSAT);
+ break;
+ case D3DSTENCILOP_DECRSAT:
+ renderer->setStencilZFailOperationCCW(sw::Context::OPERATION_DECRSAT);
+ break;
+ case D3DSTENCILOP_INVERT:
+ renderer->setStencilZFailOperationCCW(sw::Context::OPERATION_INVERT);
+ break;
+ case D3DSTENCILOP_INCR:
+ renderer->setStencilZFailOperationCCW(sw::Context::OPERATION_INCR);
+ break;
+ case D3DSTENCILOP_DECR:
+ renderer->setStencilZFailOperationCCW(sw::Context::OPERATION_DECR);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_CCW_STENCILPASS:
+ switch(value)
+ {
+ case D3DSTENCILOP_KEEP:
+ renderer->setStencilPassOperationCCW(sw::Context::OPERATION_KEEP);
+ break;
+ case D3DSTENCILOP_ZERO:
+ renderer->setStencilPassOperationCCW(sw::Context::OPERATION_ZERO);
+ break;
+ case D3DSTENCILOP_REPLACE:
+ renderer->setStencilPassOperationCCW(sw::Context::OPERATION_REPLACE);
+ break;
+ case D3DSTENCILOP_INCRSAT:
+ renderer->setStencilPassOperationCCW(sw::Context::OPERATION_INCRSAT);
+ break;
+ case D3DSTENCILOP_DECRSAT:
+ renderer->setStencilPassOperationCCW(sw::Context::OPERATION_DECRSAT);
+ break;
+ case D3DSTENCILOP_INVERT:
+ renderer->setStencilPassOperationCCW(sw::Context::OPERATION_INVERT);
+ break;
+ case D3DSTENCILOP_INCR:
+ renderer->setStencilPassOperationCCW(sw::Context::OPERATION_INCR);
+ break;
+ case D3DSTENCILOP_DECR:
+ renderer->setStencilPassOperationCCW(sw::Context::OPERATION_DECR);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_CCW_STENCILFUNC:
+ switch(value)
+ {
+ case D3DCMP_NEVER:
+ renderer->setStencilCompareCCW(sw::Context::STENCIL_NEVER);
+ break;
+ case D3DCMP_LESS:
+ renderer->setStencilCompareCCW(sw::Context::STENCIL_LESS);
+ break;
+ case D3DCMP_EQUAL:
+ renderer->setStencilCompareCCW(sw::Context::STENCIL_EQUAL);
+ break;
+ case D3DCMP_LESSEQUAL:
+ renderer->setStencilCompareCCW(sw::Context::STENCIL_LESSEQUAL);
+ break;
+ case D3DCMP_GREATER:
+ renderer->setStencilCompareCCW(sw::Context::STENCIL_GREATER);
+ break;
+ case D3DCMP_NOTEQUAL:
+ renderer->setStencilCompareCCW(sw::Context::STENCIL_NOTEQUAL);
+ break;
+ case D3DCMP_GREATEREQUAL:
+ renderer->setStencilCompareCCW(sw::Context::STENCIL_GREATEREQUAL);
+ break;
+ case D3DCMP_ALWAYS:
+ renderer->setStencilCompareCCW(sw::Context::STENCIL_ALWAYS);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_COLORWRITEENABLE1:
+ renderer->setColorWriteMask(1, value);
+ break;
+ case D3DRS_COLORWRITEENABLE2:
+ renderer->setColorWriteMask(2, value);
+ break;
+ case D3DRS_COLORWRITEENABLE3:
+ renderer->setColorWriteMask(3, value);
+ break;
+ case D3DRS_BLENDFACTOR:
+ renderer->setBlendConstant(sw::Color<float>(value));
+ break;
+ case D3DRS_SRGBWRITEENABLE:
+ renderer->setWriteSRGB(value != FALSE);
+ break;
+ case D3DRS_DEPTHBIAS:
+ renderer->setDepthBias((float&)value);
+ break;
+ case D3DRS_WRAP8:
+ renderer->setTextureWrap(8, value);
+ break;
+ case D3DRS_WRAP9:
+ renderer->setTextureWrap(9, value);
+ break;
+ case D3DRS_WRAP10:
+ renderer->setTextureWrap(10, value);
+ break;
+ case D3DRS_WRAP11:
+ renderer->setTextureWrap(11, value);
+ break;
+ case D3DRS_WRAP12:
+ renderer->setTextureWrap(12, value);
+ break;
+ case D3DRS_WRAP13:
+ renderer->setTextureWrap(13, value);
+ break;
+ case D3DRS_WRAP14:
+ renderer->setTextureWrap(14, value);
+ break;
+ case D3DRS_WRAP15:
+ renderer->setTextureWrap(15, value);
+ break;
+ case D3DRS_SEPARATEALPHABLENDENABLE:
+ renderer->setSeparateAlphaBlendEnable(value != FALSE);
+ break;
+ case D3DRS_SRCBLENDALPHA:
+ switch(value)
+ {
+ case D3DBLEND_ZERO:
+ renderer->setSourceBlendFactorAlpha(sw::Context::BLEND_ZERO);
+ break;
+ case D3DBLEND_ONE:
+ renderer->setSourceBlendFactorAlpha(sw::Context::BLEND_ONE);
+ break;
+ case D3DBLEND_SRCCOLOR:
+ renderer->setSourceBlendFactorAlpha(sw::Context::BLEND_SOURCE);
+ break;
+ case D3DBLEND_INVSRCCOLOR:
+ renderer->setSourceBlendFactorAlpha(sw::Context::BLEND_INVSOURCE);
+ break;
+ case D3DBLEND_SRCALPHA:
+ renderer->setSourceBlendFactorAlpha(sw::Context::BLEND_SOURCEALPHA);
+ break;
+ case D3DBLEND_INVSRCALPHA:
+ renderer->setSourceBlendFactorAlpha(sw::Context::BLEND_INVSOURCEALPHA);
+ break;
+ case D3DBLEND_DESTALPHA:
+ renderer->setSourceBlendFactorAlpha(sw::Context::BLEND_DESTALPHA);
+ break;
+ case D3DBLEND_INVDESTALPHA:
+ renderer->setSourceBlendFactorAlpha(sw::Context::BLEND_INVDESTALPHA);
+ break;
+ case D3DBLEND_DESTCOLOR:
+ renderer->setSourceBlendFactorAlpha(sw::Context::BLEND_DEST);
+ break;
+ case D3DBLEND_INVDESTCOLOR:
+ renderer->setSourceBlendFactorAlpha(sw::Context::BLEND_INVDEST);
+ break;
+ case D3DBLEND_SRCALPHASAT:
+ renderer->setSourceBlendFactorAlpha(sw::Context::BLEND_SRCALPHASAT);
+ break;
+ case D3DBLEND_BOTHSRCALPHA:
+ renderer->setSourceBlendFactorAlpha(sw::Context::BLEND_SOURCEALPHA);
+ renderer->setDestBlendFactorAlpha(sw::Context::BLEND_INVSOURCEALPHA);
+ break;
+ case D3DBLEND_BOTHINVSRCALPHA:
+ renderer->setSourceBlendFactorAlpha(sw::Context::BLEND_INVSOURCEALPHA);
+ renderer->setDestBlendFactorAlpha(sw::Context::BLEND_SOURCEALPHA);
+ break;
+ case D3DBLEND_BLENDFACTOR:
+ renderer->setSourceBlendFactorAlpha(sw::Context::BLEND_CONSTANT);
+ break;
+ case D3DBLEND_INVBLENDFACTOR:
+ renderer->setSourceBlendFactorAlpha(sw::Context::BLEND_INVCONSTANT);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_DESTBLENDALPHA:
+ switch(value)
+ {
+ case D3DBLEND_ZERO:
+ renderer->setDestBlendFactorAlpha(sw::Context::BLEND_ZERO);
+ break;
+ case D3DBLEND_ONE:
+ renderer->setDestBlendFactorAlpha(sw::Context::BLEND_ONE);
+ break;
+ case D3DBLEND_SRCCOLOR:
+ renderer->setDestBlendFactorAlpha(sw::Context::BLEND_SOURCE);
+ break;
+ case D3DBLEND_INVSRCCOLOR:
+ renderer->setDestBlendFactorAlpha(sw::Context::BLEND_INVSOURCE);
+ break;
+ case D3DBLEND_SRCALPHA:
+ renderer->setDestBlendFactorAlpha(sw::Context::BLEND_SOURCEALPHA);
+ break;
+ case D3DBLEND_INVSRCALPHA:
+ renderer->setDestBlendFactorAlpha(sw::Context::BLEND_INVSOURCEALPHA);
+ break;
+ case D3DBLEND_DESTALPHA:
+ renderer->setDestBlendFactorAlpha(sw::Context::BLEND_DESTALPHA);
+ break;
+ case D3DBLEND_INVDESTALPHA:
+ renderer->setDestBlendFactorAlpha(sw::Context::BLEND_INVDESTALPHA);
+ break;
+ case D3DBLEND_DESTCOLOR:
+ renderer->setDestBlendFactorAlpha(sw::Context::BLEND_DEST);
+ break;
+ case D3DBLEND_INVDESTCOLOR:
+ renderer->setDestBlendFactorAlpha(sw::Context::BLEND_INVDEST);
+ break;
+ case D3DBLEND_SRCALPHASAT:
+ renderer->setDestBlendFactorAlpha(sw::Context::BLEND_SRCALPHASAT);
+ break;
+ case D3DBLEND_BOTHSRCALPHA:
+ renderer->setSourceBlendFactorAlpha(sw::Context::BLEND_SOURCEALPHA);
+ renderer->setDestBlendFactorAlpha(sw::Context::BLEND_INVSOURCEALPHA);
+ break;
+ case D3DBLEND_BOTHINVSRCALPHA:
+ renderer->setSourceBlendFactorAlpha(sw::Context::BLEND_INVSOURCEALPHA);
+ renderer->setDestBlendFactorAlpha(sw::Context::BLEND_SOURCEALPHA);
+ break;
+ case D3DBLEND_BLENDFACTOR:
+ renderer->setDestBlendFactorAlpha(sw::Context::BLEND_CONSTANT);
+ break;
+ case D3DBLEND_INVBLENDFACTOR:
+ renderer->setDestBlendFactorAlpha(sw::Context::BLEND_INVCONSTANT);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DRS_BLENDOPALPHA:
+ switch(value)
+ {
+ case D3DBLENDOP_ADD:
+ renderer->setBlendOperationAlpha(sw::Context::BLENDOP_ADD);
+ break;
+ case D3DBLENDOP_SUBTRACT:
+ renderer->setBlendOperationAlpha(sw::Context::BLENDOP_SUB);
+ break;
+ case D3DBLENDOP_REVSUBTRACT:
+ renderer->setBlendOperationAlpha(sw::Context::BLENDOP_INVSUB);
+ break;
+ case D3DBLENDOP_MIN:
+ renderer->setBlendOperationAlpha(sw::Context::BLENDOP_MIN);
+ break;
+ case D3DBLENDOP_MAX:
+ renderer->setBlendOperationAlpha(sw::Context::BLENDOP_MAX);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ default:
+ ASSERT(false);
+ }
+ }
+ else // stateRecorder
+ {
+ stateRecorder->setRenderState(state, value);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetRenderTarget(unsigned long index, IDirect3DSurface9 *iRenderTarget)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned long index = %d, IDirect3DSurface9 *newRenderTarget = 0x%0.8p", index, iRenderTarget);
+
+ // FIXME: Check for D3DUSAGE_RENDERTARGET
+
+ if(index >= 4 || (index == 0 && !iRenderTarget))
+ {
+ return INVALIDCALL();
+ }
+
+ Direct3DSurface9 *renderTarget = static_cast<Direct3DSurface9*>(iRenderTarget);
+
+ if(renderTarget)
+ {
+ renderTarget->bind();
+ }
+
+ if(this->renderTarget[index])
+ {
+ this->renderTarget[index]->unbind();
+ }
+
+ this->renderTarget[index] = renderTarget;
+
+ if(renderTarget && index == 0)
+ {
+ D3DSURFACE_DESC renderTargetDesc;
+ renderTarget->GetDesc(&renderTargetDesc);
+
+ // Reset viewport to size of current render target
+ viewport.X = 0;
+ viewport.Y = 0;
+ viewport.Width = renderTargetDesc.Width;
+ viewport.Height = renderTargetDesc.Height;
+ viewport.MinZ = 0;
+ viewport.MaxZ = 1;
+
+ // Reset scissor rectangle to size of current render target
+ scissorRect.left = 0;
+ scissorRect.top = 0;
+ scissorRect.right = renderTargetDesc.Width;
+ scissorRect.bottom = renderTargetDesc.Height;
+
+ // Set the multi-sample mask, if maskable
+ if(renderTargetDesc.MultiSampleType != D3DMULTISAMPLE_NONE &&
+ renderTargetDesc.MultiSampleType != D3DMULTISAMPLE_NONMASKABLE)
+ {
+ renderer->setMultiSampleMask(renderState[D3DRS_MULTISAMPLEMASK]);
+ }
+ else
+ {
+ renderer->setMultiSampleMask(0xFFFFFFFF);
+ }
+ }
+
+ renderer->setRenderTarget(index, renderTarget);
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE state, unsigned long value)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned long sampler = %d, D3DSAMPLERSTATETYPE state = %d, unsigned long value = %d", sampler, state, value);
+
+ if(state < D3DSAMP_ADDRESSU || state > D3DSAMP_DMAPOFFSET)
+ {
+ return INVALIDCALL();
+ }
+
+ if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
+ {
+ return INVALIDCALL();
+ }
+
+ if(sampler >= D3DVERTEXTEXTURESAMPLER0)
+ {
+ sampler = 16 + (sampler - D3DVERTEXTEXTURESAMPLER0);
+ }
+
+ if(!stateRecorder)
+ {
+ if(!init && samplerState[sampler][state] == value)
+ {
+ return D3D_OK;
+ }
+
+ samplerState[sampler][state] = value;
+
+ sw::SamplerType type = sampler < 16 ? sw::SAMPLER_PIXEL : sw::SAMPLER_VERTEX;
+ int index = sampler < 16 ? sampler : sampler - 16; // Sampler index within type group
+
+ switch(state)
+ {
+ case D3DSAMP_ADDRESSU:
+ switch(value)
+ {
+ case D3DTADDRESS_WRAP:
+ renderer->setAddressingModeU(type, index, sw::ADDRESSING_WRAP);
+ break;
+ case D3DTADDRESS_MIRROR:
+ renderer->setAddressingModeU(type, index, sw::ADDRESSING_MIRROR);
+ break;
+ case D3DTADDRESS_CLAMP:
+ renderer->setAddressingModeU(type, index, sw::ADDRESSING_CLAMP);
+ break;
+ case D3DTADDRESS_BORDER:
+ renderer->setAddressingModeU(type, index, sw::ADDRESSING_BORDER);
+ break;
+ case D3DTADDRESS_MIRRORONCE:
+ renderer->setAddressingModeU(type, index, sw::ADDRESSING_MIRRORONCE);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DSAMP_ADDRESSV:
+ switch(value)
+ {
+ case D3DTADDRESS_WRAP:
+ renderer->setAddressingModeV(type, index, sw::ADDRESSING_WRAP);
+ break;
+ case D3DTADDRESS_MIRROR:
+ renderer->setAddressingModeV(type, index, sw::ADDRESSING_MIRROR);
+ break;
+ case D3DTADDRESS_CLAMP:
+ renderer->setAddressingModeV(type, index, sw::ADDRESSING_CLAMP);
+ break;
+ case D3DTADDRESS_BORDER:
+ renderer->setAddressingModeV(type, index, sw::ADDRESSING_BORDER);
+ break;
+ case D3DTADDRESS_MIRRORONCE:
+ renderer->setAddressingModeV(type, index, sw::ADDRESSING_MIRRORONCE);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DSAMP_ADDRESSW:
+ switch(value)
+ {
+ case D3DTADDRESS_WRAP:
+ renderer->setAddressingModeW(type, index, sw::ADDRESSING_WRAP);
+ break;
+ case D3DTADDRESS_MIRROR:
+ renderer->setAddressingModeW(type, index, sw::ADDRESSING_MIRROR);
+ break;
+ case D3DTADDRESS_CLAMP:
+ renderer->setAddressingModeW(type, index, sw::ADDRESSING_CLAMP);
+ break;
+ case D3DTADDRESS_BORDER:
+ renderer->setAddressingModeW(type, index, sw::ADDRESSING_BORDER);
+ break;
+ case D3DTADDRESS_MIRRORONCE:
+ renderer->setAddressingModeW(type, index, sw::ADDRESSING_MIRRORONCE);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DSAMP_BORDERCOLOR:
+ renderer->setBorderColor(type, index, value);
+ break;
+ case D3DSAMP_MAGFILTER:
+ // NOTE: SwiftShader does not differentiate between minification and magnification filter
+ switch(value)
+ {
+ case D3DTEXF_NONE:
+ renderer->setTextureFilter(type, index, sw::FILTER_POINT); // FIXME: Only for mipmap filter
+ break;
+ case D3DTEXF_POINT:
+ renderer->setTextureFilter(type, index, sw::FILTER_POINT);
+ break;
+ case D3DTEXF_LINEAR:
+ renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);
+ break;
+ case D3DTEXF_ANISOTROPIC:
+ renderer->setTextureFilter(type, index, sw::FILTER_ANISOTROPIC);
+ break;
+ case D3DTEXF_PYRAMIDALQUAD:
+ renderer->setTextureFilter(type, index, sw::FILTER_LINEAR); // FIXME: Unimplemented, fail silently
+ break;
+ case D3DTEXF_GAUSSIANQUAD:
+ renderer->setTextureFilter(type, index, sw::FILTER_LINEAR); // FIXME: Unimplemented, fail silently
+ break;
+ default:
+ return INVALIDCALL();
+ };
+ break;
+ case D3DSAMP_MINFILTER:
+ // NOTE: SwiftShader does not differentiate between minification and magnification filter
+ switch(value)
+ {
+ case D3DTEXF_NONE:
+ renderer->setTextureFilter(type, index, sw::FILTER_POINT); // FIXME: Only for mipmap filter
+ break;
+ case D3DTEXF_POINT:
+ renderer->setTextureFilter(type, index, sw::FILTER_POINT);
+ break;
+ case D3DTEXF_LINEAR:
+ renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);
+ break;
+ case D3DTEXF_ANISOTROPIC:
+ renderer->setTextureFilter(type, index, sw::FILTER_ANISOTROPIC);
+ break;
+ case D3DTEXF_PYRAMIDALQUAD:
+ renderer->setTextureFilter(type, index, sw::FILTER_LINEAR); // FIXME: Unimplemented, fail silently
+ break;
+ case D3DTEXF_GAUSSIANQUAD:
+ renderer->setTextureFilter(type, index, sw::FILTER_LINEAR); // FIXME: Unimplemented, fail silently
+ break;
+ default:
+ return INVALIDCALL();
+ };
+ break;
+ case D3DSAMP_MIPFILTER:
+ switch(value)
+ {
+ case D3DTEXF_NONE:
+ renderer->setMipmapFilter(type, index, sw::MIPMAP_NONE);
+ break;
+ case D3DTEXF_POINT:
+ renderer->setMipmapFilter(type, index, sw::MIPMAP_POINT);
+ break;
+ case D3DTEXF_LINEAR:
+ renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR);
+ break;
+ case D3DTEXF_ANISOTROPIC:
+ renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR); // FIXME: Only for texture filter
+ break;
+ case D3DTEXF_PYRAMIDALQUAD:
+ renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR); // FIXME: Only for texture filter
+ break;
+ case D3DTEXF_GAUSSIANQUAD:
+ renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR); // FIXME: Only for texture filter
+ break;
+ default:
+ return INVALIDCALL();
+ };
+ break;
+ case D3DSAMP_MIPMAPLODBIAS:
+ if(value == D3DFMT_GET4) // ATI hack to enable Fetch4
+ {
+ renderer->setGatherEnable(type, index, true);
+ }
+ else if(value == D3DFMT_GET1) // ATI hack to disable Fetch4
+ {
+ renderer->setGatherEnable(type, index, false);
+ }
+ else
+ {
+ float LOD = (float&)value - sw::log2((float)context->renderTarget[0]->getSuperSampleCount()); // FIXME: Update when render target changes
+ renderer->setMipmapLOD(type, index, LOD);
+ }
+ break;
+ case D3DSAMP_MAXMIPLEVEL:
+ break;
+ case D3DSAMP_MAXANISOTROPY:
+ renderer->setMaxAnisotropy(type, index, sw::clamp((unsigned int)value, (unsigned int)1, maxAnisotropy));
+ break;
+ case D3DSAMP_SRGBTEXTURE:
+ renderer->setReadSRGB(type, index, value != FALSE);
+ break;
+ case D3DSAMP_ELEMENTINDEX:
+ if(!init) UNIMPLEMENTED(); // Multi-element textures deprecated in favor of multiple render targets
+ break;
+ case D3DSAMP_DMAPOFFSET:
+ // if(!init) UNIMPLEMENTED();
+ break;
+ default:
+ ASSERT(false);
+ }
+ }
+ else // stateRecorder
+ {
+ stateRecorder->setSamplerState(sampler, state, value);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetScissorRect(const RECT *rect)
+ {
+ CriticalSection cs(this);
+
+ TRACE("const RECT *rect = 0x%0.8p", rect);
+
+ if(!rect)
+ {
+ return INVALIDCALL();
+ }
+
+ if(!stateRecorder)
+ {
+ scissorRect = *rect;
+ }
+ else
+ {
+ stateRecorder->setScissorRect(rect);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetSoftwareVertexProcessing(int software)
+ {
+ CriticalSection cs(this);
+
+ TRACE("int software = %d", software);
+
+ if(behaviourFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING && software == FALSE)
+ {
+ return INVALIDCALL();
+ }
+
+ if(behaviourFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING && software == TRUE)
+ {
+ return INVALIDCALL();
+ }
+
+ softwareVertexProcessing = (software != FALSE);
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetStreamSource(unsigned int stream, IDirect3DVertexBuffer9 *iVertexBuffer, unsigned int offset, unsigned int stride)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int stream = %d, IDirect3DVertexBuffer9 *data = 0x%0.8p, unsigned int offset = %d, unsigned int stride = %d", stream, iVertexBuffer, offset, stride);
+
+ Direct3DVertexBuffer9 *vertexBuffer = static_cast<Direct3DVertexBuffer9*>(iVertexBuffer);
+
+ if(!stateRecorder)
+ {
+ if(dataStream[stream] == vertexBuffer && streamOffset[stream] == offset && streamStride[stream] == stride)
+ {
+ return D3D_OK;
+ }
+
+ if(vertexBuffer)
+ {
+ vertexBuffer->bind();
+ }
+
+ if(dataStream[stream])
+ {
+ dataStream[stream]->unbind();
+ }
+
+ dataStream[stream] = vertexBuffer;
+ streamOffset[stream] = offset;
+ streamStride[stream] = stride;
+ }
+ else
+ {
+ stateRecorder->setStreamSource(stream, vertexBuffer, offset, stride);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetStreamSourceFreq(unsigned int streamNumber, unsigned int divider)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int streamNumber = %d, unsigned int divider = %d", streamNumber, divider);
+
+ if(!instancingEnabled)
+ {
+ return INVALIDCALL();
+ }
+
+ if(!stateRecorder)
+ {
+ streamSourceFreq[streamNumber] = divider;
+ }
+ else
+ {
+ stateRecorder->setStreamSourceFreq(streamNumber, divider);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetTexture(unsigned long sampler, IDirect3DBaseTexture9 *iBaseTexture)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned long sampler = %d, IDirect3DBaseTexture9 *texture = 0x%0.8p", sampler, iBaseTexture);
+
+ if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
+ {
+ return INVALIDCALL();
+ }
+
+ if(sampler >= D3DVERTEXTEXTURESAMPLER0)
+ {
+ sampler = 16 + (sampler - D3DVERTEXTEXTURESAMPLER0);
+ }
+
+ Direct3DBaseTexture9 *baseTexture = dynamic_cast<Direct3DBaseTexture9*>(iBaseTexture);
+
+ if(!stateRecorder)
+ {
+ if(texture[sampler] == baseTexture)
+ {
+ return D3D_OK;
+ }
+
+ if(baseTexture)
+ {
+ baseTexture->bind(); // FIXME: Bind individual sub-surfaces?
+ }
+
+ if(texture[sampler])
+ {
+ texture[sampler]->unbind();
+ }
+
+ texture[sampler] = baseTexture;
+ }
+ else
+ {
+ stateRecorder->setTexture(sampler, baseTexture);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long value)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned long stage = %d, D3DTEXTURESTAGESTATETYPE type = %d, unsigned long value = %d", stage, type, value);
+
+ if(stage < 0 || stage >= 8 || type < D3DTSS_COLOROP || type > D3DTSS_CONSTANT)
+ {
+ return INVALIDCALL();
+ }
+
+ if(!stateRecorder)
+ {
+ if(!init && textureStageState[stage][type] == value)
+ {
+ return D3D_OK;
+ }
+
+ textureStageState[stage][type] = value;
+
+ switch(type)
+ {
+ case D3DTSS_COLOROP:
+ switch(value)
+ {
+ case D3DTOP_DISABLE:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_DISABLE);
+ break;
+ case D3DTOP_SELECTARG1:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_SELECTARG1);
+ break;
+ case D3DTOP_SELECTARG2:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_SELECTARG2);
+ break;
+ case D3DTOP_MODULATE:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE);
+ break;
+ case D3DTOP_MODULATE2X:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE2X);
+ break;
+ case D3DTOP_MODULATE4X:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE4X);
+ break;
+ case D3DTOP_ADD:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADD);
+ break;
+ case D3DTOP_ADDSIGNED:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSIGNED);
+ break;
+ case D3DTOP_ADDSIGNED2X:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSIGNED2X);
+ break;
+ case D3DTOP_SUBTRACT:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_SUBTRACT);
+ break;
+ case D3DTOP_ADDSMOOTH:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSMOOTH);
+ break;
+ case D3DTOP_BLENDDIFFUSEALPHA:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDDIFFUSEALPHA);
+ break;
+ case D3DTOP_BLENDTEXTUREALPHA:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);
+ break;
+ case D3DTOP_BLENDFACTORALPHA:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDFACTORALPHA);
+ break;
+ case D3DTOP_BLENDTEXTUREALPHAPM:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHAPM);
+ break;
+ case D3DTOP_BLENDCURRENTALPHA:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDCURRENTALPHA);
+ break;
+ case D3DTOP_PREMODULATE:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_PREMODULATE);
+ break;
+ case D3DTOP_MODULATEALPHA_ADDCOLOR:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEALPHA_ADDCOLOR);
+ break;
+ case D3DTOP_MODULATECOLOR_ADDALPHA:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATECOLOR_ADDALPHA);
+ break;
+ case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR);
+ break;
+ case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA);
+ break;
+ case D3DTOP_BUMPENVMAP:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_BUMPENVMAP);
+ break;
+ case D3DTOP_BUMPENVMAPLUMINANCE:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_BUMPENVMAPLUMINANCE);
+ break;
+ case D3DTOP_DOTPRODUCT3:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_DOT3);
+ break;
+ case D3DTOP_MULTIPLYADD:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_MULTIPLYADD);
+ break;
+ case D3DTOP_LERP:
+ renderer->setStageOperation(stage, sw::TextureStage::STAGE_LERP);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DTSS_COLORARG1:
+ switch(value & D3DTA_SELECTMASK)
+ {
+ case D3DTA_DIFFUSE:
+ renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);
+ break;
+ case D3DTA_CURRENT:
+ renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_CURRENT);
+ break;
+ case D3DTA_TEXTURE:
+ renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TEXTURE);
+ break;
+ case D3DTA_TFACTOR:
+ renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TFACTOR);
+ break;
+ case D3DTA_SPECULAR:
+ renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_SPECULAR);
+ break;
+ case D3DTA_TEMP:
+ renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TEMP);
+ break;
+ case D3DTA_CONSTANT:
+ renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_CONSTANT);
+ break;
+ default:
+ ASSERT(false);
+ }
+
+ switch(value & ~D3DTA_SELECTMASK)
+ {
+ case 0:
+ renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_COLOR);
+ break;
+ case D3DTA_COMPLEMENT:
+ renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);
+ break;
+ case D3DTA_ALPHAREPLICATE:
+ renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_ALPHA);
+ break;
+ case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
+ renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DTSS_COLORARG2:
+ switch(value & D3DTA_SELECTMASK)
+ {
+ case D3DTA_DIFFUSE:
+ renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);
+ break;
+ case D3DTA_CURRENT:
+ renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_CURRENT);
+ break;
+ case D3DTA_TEXTURE:
+ renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TEXTURE);
+ break;
+ case D3DTA_TFACTOR:
+ renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TFACTOR);
+ break;
+ case D3DTA_SPECULAR:
+ renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_SPECULAR);
+ break;
+ case D3DTA_TEMP:
+ renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TEMP);
+ break;
+ case D3DTA_CONSTANT:
+ renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_CONSTANT);
+ break;
+ default:
+ ASSERT(false);
+ }
+
+ switch(value & ~D3DTA_SELECTMASK)
+ {
+ case 0:
+ renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_COLOR);
+ break;
+ case D3DTA_COMPLEMENT:
+ renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);
+ break;
+ case D3DTA_ALPHAREPLICATE:
+ renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_ALPHA);
+ break;
+ case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
+ renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DTSS_ALPHAOP:
+ switch(value)
+ {
+ case D3DTOP_DISABLE:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_DISABLE);
+ break;
+ case D3DTOP_SELECTARG1:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SELECTARG1);
+ break;
+ case D3DTOP_SELECTARG2:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SELECTARG2);
+ break;
+ case D3DTOP_MODULATE:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE);
+ break;
+ case D3DTOP_MODULATE2X:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE2X);
+ break;
+ case D3DTOP_MODULATE4X:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE4X);
+ break;
+ case D3DTOP_ADD:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADD);
+ break;
+ case D3DTOP_ADDSIGNED:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSIGNED);
+ break;
+ case D3DTOP_ADDSIGNED2X:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSIGNED2X);
+ break;
+ case D3DTOP_SUBTRACT:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SUBTRACT);
+ break;
+ case D3DTOP_ADDSMOOTH:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSMOOTH);
+ break;
+ case D3DTOP_BLENDDIFFUSEALPHA:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDDIFFUSEALPHA);
+ break;
+ case D3DTOP_BLENDTEXTUREALPHA:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);
+ break;
+ case D3DTOP_BLENDFACTORALPHA:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDFACTORALPHA);
+ break;
+ case D3DTOP_BLENDTEXTUREALPHAPM:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHAPM);
+ break;
+ case D3DTOP_BLENDCURRENTALPHA:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDCURRENTALPHA);
+ break;
+ case D3DTOP_PREMODULATE:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_PREMODULATE);
+ break;
+ case D3DTOP_MODULATEALPHA_ADDCOLOR:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEALPHA_ADDCOLOR);
+ break;
+ case D3DTOP_MODULATECOLOR_ADDALPHA:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATECOLOR_ADDALPHA);
+ break;
+ case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR);
+ break;
+ case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA);
+ break;
+ case D3DTOP_BUMPENVMAP:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BUMPENVMAP);
+ break;
+ case D3DTOP_BUMPENVMAPLUMINANCE:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BUMPENVMAPLUMINANCE);
+ break;
+ case D3DTOP_DOTPRODUCT3:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_DOT3);
+ break;
+ case D3DTOP_MULTIPLYADD:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MULTIPLYADD);
+ break;
+ case D3DTOP_LERP:
+ renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_LERP);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DTSS_ALPHAARG1:
+ switch(value & D3DTA_SELECTMASK)
+ {
+ case D3DTA_DIFFUSE:
+ renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);
+ break;
+ case D3DTA_CURRENT:
+ renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);
+ break;
+ case D3DTA_TEXTURE:
+ renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);
+ break;
+ case D3DTA_TFACTOR:
+ renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);
+ break;
+ case D3DTA_SPECULAR:
+ renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);
+ break;
+ case D3DTA_TEMP:
+ renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);
+ break;
+ case D3DTA_CONSTANT:
+ renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_CONSTANT);
+ break;
+ default:
+ ASSERT(false);
+ }
+
+ switch(value & ~D3DTA_SELECTMASK)
+ {
+ case 0:
+ renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);
+ break;
+ case D3DTA_COMPLEMENT:
+ renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);
+ break;
+ case D3DTA_ALPHAREPLICATE:
+ renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);
+ break;
+ case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
+ renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DTSS_ALPHAARG2:
+ switch(value & D3DTA_SELECTMASK)
+ {
+ case D3DTA_DIFFUSE:
+ renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);
+ break;
+ case D3DTA_CURRENT:
+ renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);
+ break;
+ case D3DTA_TEXTURE:
+ renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);
+ break;
+ case D3DTA_TFACTOR:
+ renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);
+ break;
+ case D3DTA_SPECULAR:
+ renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);
+ break;
+ case D3DTA_TEMP:
+ renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);
+ break;
+ case D3DTA_CONSTANT:
+ renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_CONSTANT);
+ break;
+ default:
+ ASSERT(false);
+ }
+
+ switch(value & ~D3DTA_SELECTMASK)
+ {
+ case 0:
+ renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);
+ break;
+ case D3DTA_COMPLEMENT:
+ renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);
+ break;
+ case D3DTA_ALPHAREPLICATE:
+ renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);
+ break;
+ case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
+ renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_INVALPHA);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DTSS_BUMPENVMAT00:
+ renderer->setBumpmapMatrix(stage, 0, (float&)value);
+ break;
+ case D3DTSS_BUMPENVMAT01:
+ renderer->setBumpmapMatrix(stage, 1, (float&)value);
+ break;
+ case D3DTSS_BUMPENVMAT10:
+ renderer->setBumpmapMatrix(stage, 2, (float&)value);
+ break;
+ case D3DTSS_BUMPENVMAT11:
+ renderer->setBumpmapMatrix(stage, 3, (float&)value);
+ break;
+ case D3DTSS_TEXCOORDINDEX:
+ renderer->setTexCoordIndex(stage, value & 0x0000FFFF);
+
+ switch(value & 0xFFFF0000)
+ {
+ case D3DTSS_TCI_PASSTHRU:
+ renderer->setTexGen(stage, sw::Context::TEXGEN_PASSTHRU);
+ break;
+ case D3DTSS_TCI_CAMERASPACENORMAL:
+ renderer->setTexCoordIndex(stage, stage);
+ renderer->setTexGen(stage, sw::Context::TEXGEN_NORMAL);
+ break;
+ case D3DTSS_TCI_CAMERASPACEPOSITION:
+ renderer->setTexCoordIndex(stage, stage);
+ renderer->setTexGen(stage, sw::Context::TEXGEN_POSITION);
+ break;
+ case D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
+ renderer->setTexCoordIndex(stage, stage);
+ renderer->setTexGen(stage, sw::Context::TEXGEN_REFLECTION);
+ break;
+ case D3DTSS_TCI_SPHEREMAP:
+ renderer->setTexCoordIndex(stage, stage);
+ renderer->setTexGen(stage, sw::Context::TEXGEN_SPHEREMAP);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DTSS_BUMPENVLSCALE:
+ renderer->setLuminanceScale(stage, (float&)value);
+ break;
+ case D3DTSS_BUMPENVLOFFSET:
+ renderer->setLuminanceOffset(stage, (float&)value);
+ break;
+ case D3DTSS_TEXTURETRANSFORMFLAGS:
+ switch(value & ~D3DTTFF_PROJECTED)
+ {
+ case D3DTTFF_DISABLE:
+ renderer->setTextureTransform(stage, 0, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
+ break;
+ case D3DTTFF_COUNT1:
+ renderer->setTextureTransform(stage, 1, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
+ break;
+ case D3DTTFF_COUNT2:
+ renderer->setTextureTransform(stage, 2, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
+ break;
+ case D3DTTFF_COUNT3:
+ renderer->setTextureTransform(stage, 3, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
+ break;
+ case D3DTTFF_COUNT4:
+ renderer->setTextureTransform(stage, 4, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DTSS_COLORARG0:
+ switch(value & D3DTA_SELECTMASK)
+ {
+ case D3DTA_CURRENT:
+ renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_CURRENT);
+ break;
+ case D3DTA_DIFFUSE:
+ renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);
+ break;
+ case D3DTA_SPECULAR:
+ renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_SPECULAR);
+ break;
+ case D3DTA_TEMP:
+ renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TEMP);
+ break;
+ case D3DTA_TEXTURE:
+ renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TEXTURE);
+ break;
+ case D3DTA_TFACTOR:
+ renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TFACTOR);
+ break;
+ default:
+ ASSERT(false);
+ }
+
+ switch(value & ~D3DTA_SELECTMASK)
+ {
+ case 0:
+ renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_COLOR);
+ break;
+ case D3DTA_COMPLEMENT:
+ renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);
+ break;
+ case D3DTA_ALPHAREPLICATE:
+ renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_ALPHA);
+ break;
+ case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
+ renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DTSS_ALPHAARG0:
+ switch(value & D3DTA_SELECTMASK)
+ {
+ case D3DTA_DIFFUSE:
+ renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);
+ break;
+ case D3DTA_CURRENT:
+ renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);
+ break;
+ case D3DTA_TEXTURE:
+ renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);
+ break;
+ case D3DTA_TFACTOR:
+ renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);
+ break;
+ case D3DTA_SPECULAR:
+ renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);
+ break;
+ case D3DTA_TEMP:
+ renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);
+ break;
+ case D3DTA_CONSTANT:
+ renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_CONSTANT);
+ break;
+ default:
+ ASSERT(false);
+ }
+
+ switch(value & ~D3DTA_SELECTMASK)
+ {
+ case 0:
+ renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);
+ break;
+ case D3DTA_COMPLEMENT:
+ renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);
+ break;
+ case D3DTA_ALPHAREPLICATE:
+ renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);
+ break;
+ case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
+ renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_INVALPHA);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DTSS_RESULTARG:
+ switch(value & D3DTA_SELECTMASK)
+ {
+ case D3DTA_CURRENT:
+ renderer->setDestinationArgument(stage, sw::TextureStage::DESTINATION_CURRENT);
+ break;
+ case D3DTA_TEMP:
+ renderer->setDestinationArgument(stage, sw::TextureStage::DESTINATION_TEMP);
+ break;
+ default:
+ ASSERT(false);
+ }
+ break;
+ case D3DTSS_CONSTANT:
+ renderer->setConstantColor(stage, value);
+ break;
+ default:
+ ASSERT(false);
+ }
+ }
+ else // stateRecorder
+ {
+ stateRecorder->setTextureStageState(stage, type, value);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
+ {
+ CriticalSection cs(this);
+
+ TRACE("D3DTRANSFORMSTATETYPE state = %d, const D3DMATRIX *matrix = 0x%0.8p", state, matrix);
+
+ if(!matrix)
+ {
+ return INVALIDCALL();
+ }
+
+ if(!stateRecorder)
+ {
+ this->matrix[state] = *matrix;
+
+ sw::Matrix M(matrix->_11, matrix->_21, matrix->_31, matrix->_41,
+ matrix->_12, matrix->_22, matrix->_32, matrix->_42,
+ matrix->_13, matrix->_23, matrix->_33, matrix->_43,
+ matrix->_14, matrix->_24, matrix->_34, matrix->_44);
+
+ switch(state)
+ {
+ case D3DTS_WORLD:
+ renderer->setModelMatrix(M);
+ break;
+ case D3DTS_VIEW:
+ renderer->setViewMatrix(M);
+ break;
+ case D3DTS_PROJECTION:
+ renderer->setProjectionMatrix(M);
+ break;
+ case D3DTS_TEXTURE0:
+ renderer->setTextureMatrix(0, M);
+ break;
+ case D3DTS_TEXTURE1:
+ renderer->setTextureMatrix(1, M);
+ break;
+ case D3DTS_TEXTURE2:
+ renderer->setTextureMatrix(2, M);
+ break;
+ case D3DTS_TEXTURE3:
+ renderer->setTextureMatrix(3, M);
+ break;
+ case D3DTS_TEXTURE4:
+ renderer->setTextureMatrix(4, M);
+ break;
+ case D3DTS_TEXTURE5:
+ renderer->setTextureMatrix(5, M);
+ break;
+ case D3DTS_TEXTURE6:
+ renderer->setTextureMatrix(6, M);
+ break;
+ case D3DTS_TEXTURE7:
+ renderer->setTextureMatrix(7, M);
+ break;
+ default:
+ if(state > 256 && state < 512)
+ {
+ renderer->setModelMatrix(M, state - 256);
+ }
+ else ASSERT(false);
+ }
+ }
+ else // stateRecorder
+ {
+ stateRecorder->setTransform(state, matrix);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetVertexDeclaration(IDirect3DVertexDeclaration9 *iVertexDeclaration)
+ {
+ CriticalSection cs(this);
+
+ TRACE("IDirect3DVertexDeclaration9 *declaration = 0x%0.8p", iVertexDeclaration);
+
+ Direct3DVertexDeclaration9 *vertexDeclaration = static_cast<Direct3DVertexDeclaration9*>(iVertexDeclaration);
+
+ if(!stateRecorder)
+ {
+ if(this->vertexDeclaration == vertexDeclaration)
+ {
+ return D3D_OK;
+ }
+
+ if(vertexDeclaration)
+ {
+ vertexDeclaration->bind();
+ }
+
+ if(this->vertexDeclaration)
+ {
+ this->vertexDeclaration->unbind();
+ }
+
+ this->vertexDeclaration = vertexDeclaration;
+ }
+ else
+ {
+ stateRecorder->setVertexDeclaration(vertexDeclaration);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetVertexShader(IDirect3DVertexShader9 *iVertexShader)
+ {
+ CriticalSection cs(this);
+
+ TRACE("IDirect3DVertexShader9 *shader = 0x%0.8p", iVertexShader);
+
+ Direct3DVertexShader9 *vertexShader = static_cast<Direct3DVertexShader9*>(iVertexShader);
+
+ if(!stateRecorder)
+ {
+ if(this->vertexShader == vertexShader)
+ {
+ return D3D_OK;
+ }
+
+ if(vertexShader)
+ {
+ vertexShader->bind();
+ }
+
+ if(this->vertexShader)
+ {
+ this->vertexShader->unbind();
+ }
+
+ this->vertexShader = vertexShader;
+ vertexShaderDirty = true;
+ }
+ else
+ {
+ stateRecorder->setVertexShader(vertexShader);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetVertexShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ if(!constantData)
+ {
+ return INVALIDCALL();
+ }
+
+ if(!stateRecorder)
+ {
+ for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
+ {
+ vertexShaderConstantB[startRegister + i] = constantData[i];
+ }
+
+ vertexShaderConstantsBDirty = sw::max(startRegister + count, vertexShaderConstantsBDirty);
+ vertexShaderDirty = true; // Reload DEF constants
+ }
+ else
+ {
+ stateRecorder->setVertexShaderConstantB(startRegister, constantData, count);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ if(!constantData)
+ {
+ return INVALIDCALL();
+ }
+
+ if(!stateRecorder)
+ {
+ for(unsigned int i = 0; i < count && startRegister + i < 256; i++)
+ {
+ vertexShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0];
+ vertexShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1];
+ vertexShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2];
+ vertexShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3];
+ }
+
+ vertexShaderConstantsFDirty = sw::max(startRegister + count, vertexShaderConstantsFDirty);
+ vertexShaderDirty = true; // Reload DEF constants
+ }
+ else
+ {
+ stateRecorder->setVertexShaderConstantF(startRegister, constantData, count);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetVertexShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ if(!constantData)
+ {
+ return INVALIDCALL();
+ }
+
+ if(!stateRecorder)
+ {
+ for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
+ {
+ vertexShaderConstantI[startRegister + i][0] = constantData[i * 4 + 0];
+ vertexShaderConstantI[startRegister + i][1] = constantData[i * 4 + 1];
+ vertexShaderConstantI[startRegister + i][2] = constantData[i * 4 + 2];
+ vertexShaderConstantI[startRegister + i][3] = constantData[i * 4 + 3];
+ }
+
+ vertexShaderConstantsIDirty = sw::max(startRegister + count, vertexShaderConstantsIDirty);
+ vertexShaderDirty = true; // Reload DEF constants
+ }
+ else
+ {
+ stateRecorder->setVertexShaderConstantI(startRegister, constantData, count);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::SetViewport(const D3DVIEWPORT9 *viewport)
+ {
+ CriticalSection cs(this);
+
+ TRACE("const D3DVIEWPORT9 *viewport = 0x%0.8p", viewport);
+
+ if(!viewport) // FIXME: Check if valid
+ {
+ return INVALIDCALL();
+ }
+
+ if(!stateRecorder)
+ {
+ this->viewport = *viewport;
+ }
+ else
+ {
+ stateRecorder->setViewport(viewport);
+ }
+
+ return D3D_OK;
+ }
+
+ int Direct3DDevice9::ShowCursor(int show)
+ {
+ CriticalSection cs(this);
+
+ TRACE("int show = %d", show);
+
+ int oldValue = showCursor ? TRUE : FALSE;
+ showCursor = show != FALSE;
+
+ if(showCursor)
+ {
+ sw::FrameBuffer::setCursorImage(cursor);
+ }
+ else
+ {
+ sw::FrameBuffer::setCursorImage(0);
+ }
+
+ return oldValue;
+ }
+
+ long Direct3DDevice9::StretchRect(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destSurface, const RECT *destRect, D3DTEXTUREFILTERTYPE filter)
+ {
+ CriticalSection cs(this);
+
+ TRACE("IDirect3DSurface9 *sourceSurface = 0x%0.8p, const RECT *sourceRect = 0x%0.8p, IDirect3DSurface9 *destSurface = 0x%0.8p, const RECT *destRect = 0x%0.8p, D3DTEXTUREFILTERTYPE filter = %d", sourceSurface, sourceRect, destSurface, destRect, filter);
+
+ if(!sourceSurface || !destSurface || !validRectangle(sourceRect, sourceSurface) || !validRectangle(destRect, destSurface))
+ {
+ return INVALIDCALL();
+ }
+
+ D3DSURFACE_DESC sourceDescription;
+ D3DSURFACE_DESC destDescription;
+
+ sourceSurface->GetDesc(&sourceDescription);
+ destSurface->GetDesc(&destDescription);
+
+ if(sourceDescription.Pool != D3DPOOL_DEFAULT || destDescription.Pool != D3DPOOL_DEFAULT)
+ {
+ return INVALIDCALL();
+ }
+
+ Direct3DSurface9 *source = static_cast<Direct3DSurface9*>(sourceSurface);
+ Direct3DSurface9 *dest = static_cast<Direct3DSurface9*>(destSurface);
+
+ stretchRect(source, sourceRect, dest, destRect, filter);
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::TestCooperativeLevel()
+ {
+ CriticalSection cs(this);
+
+ TRACE("void");
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::UpdateSurface(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destinationSurface, const POINT *destPoint)
+ {
+ CriticalSection cs(this);
+
+ TRACE("IDirect3DSurface9 *sourceSurface = 0x%0.8p, const RECT *sourceRect = 0x%0.8p, IDirect3DSurface9 *destinationSurface = 0x%0.8p, const POINT *destPoint = 0x%0.8p", sourceSurface, sourceRect, destinationSurface, destPoint);
+
+ if(!sourceSurface || !destinationSurface)
+ {
+ return INVALIDCALL();
+ }
+
+ D3DSURFACE_DESC sourceDescription;
+ D3DSURFACE_DESC destinationDescription;
+
+ sourceSurface->GetDesc(&sourceDescription);
+ destinationSurface->GetDesc(&destinationDescription);
+
+ RECT sRect;
+ RECT dRect;
+
+ if(sourceRect)
+ {
+ sRect.left = sourceRect->left;
+ sRect.top = sourceRect->top;
+ sRect.right = sourceRect->right;
+ sRect.bottom = sourceRect->bottom;
+ }
+ else
+ {
+ sRect.left = 0;
+ sRect.top = 0;
+ sRect.right = sourceDescription.Width;
+ sRect.bottom = sourceDescription.Height;
+ }
+
+ if(destPoint)
+ {
+ dRect.left = destPoint->x;
+ dRect.top = destPoint->y;
+ dRect.right = destPoint->x + sRect.right - sRect.left;
+ dRect.bottom = destPoint->y + sRect.bottom - sRect.top;
+ }
+ else
+ {
+ dRect.left = 0;
+ dRect.top = 0;
+ dRect.right = sRect.right - sRect.left;
+ dRect.bottom = sRect.bottom - sRect.top;
+ }
+
+ if(!validRectangle(&sRect, sourceSurface) || !validRectangle(&dRect, destinationSurface))
+ {
+ return INVALIDCALL();
+ }
+
+ int sWidth = sRect.right - sRect.left;
+ int sHeight = sRect.bottom - sRect.top;
+
+ int dWidth = dRect.right - dRect.left;
+ int dHeight = dRect.bottom - dRect.top;
+
+ if(sourceDescription.MultiSampleType != D3DMULTISAMPLE_NONE ||
+ destinationDescription.MultiSampleType != D3DMULTISAMPLE_NONE ||
+ // sourceDescription.Pool != D3DPOOL_SYSTEMMEM || // FIXME: Check back buffer and depth buffer memory pool flags
+ // destinationDescription.Pool != D3DPOOL_DEFAULT ||
+ sourceDescription.Format != destinationDescription.Format)
+ {
+ return INVALIDCALL();
+ }
+
+ sw::Surface *source = static_cast<Direct3DSurface9*>(sourceSurface);
+ sw::Surface *dest = static_cast<Direct3DSurface9*>(destinationSurface);
+
+ unsigned char *sBuffer = (unsigned char*)source->lockExternal(sRect.left, sRect.top, 0, sw::LOCK_READONLY, sw::PUBLIC);
+ unsigned char *dBuffer = (unsigned char*)dest->lockExternal(dRect.left, dRect.top, 0, sw::LOCK_WRITEONLY, sw::PUBLIC);
+ int sPitch = source->getExternalPitchB();
+ int dPitch = dest->getExternalPitchB();
+
+ unsigned int width;
+ unsigned int height;
+ unsigned int bytes;
+
+ switch(sourceDescription.Format)
+ {
+ case D3DFMT_DXT1:
+ case D3DFMT_ATI1:
+ width = (dWidth + 3) / 4;
+ height = (dHeight + 3) / 4;
+ bytes = width * 8; // 64 bit per 4x4 block
+ break;
+ case D3DFMT_DXT2:
+ case D3DFMT_DXT3:
+ case D3DFMT_DXT4:
+ case D3DFMT_DXT5:
+ case D3DFMT_ATI2:
+ width = (dWidth + 3) / 4;
+ height = (dHeight + 3) / 4;
+ bytes = width * 16; // 128 bit per 4x4 block
+ break;
+ default:
+ width = dWidth;
+ height = dHeight;
+ bytes = width * Direct3DSurface9::bytes(sourceDescription.Format);
+ }
+
+ if(sourceDescription.Format == D3DFMT_ATI1 || sourceDescription.Format == D3DFMT_ATI2)
+ {
+ // Make the pitch correspond to 4 rows
+ sPitch *= 4;
+ dPitch *= 4;
+ }
+
+ for(unsigned int y = 0; y < height; y++)
+ {
+ memcpy(dBuffer, sBuffer, bytes);
+
+ sBuffer += sPitch;
+ dBuffer += dPitch;
+ }
+
+ source->unlockExternal();
+ dest->unlockExternal();
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::UpdateTexture(IDirect3DBaseTexture9 *sourceTexture, IDirect3DBaseTexture9 *destinationTexture)
+ {
+ CriticalSection cs(this);
+
+ TRACE("IDirect3DBaseTexture9 *sourceTexture = 0x%0.8p, IDirect3DBaseTexture9 *destinationTexture = 0x%0.8p", sourceTexture, destinationTexture);
+
+ if(!sourceTexture || !destinationTexture)
+ {
+ return INVALIDCALL();
+ }
+
+ // FIXME: Check memory pools
+
+ D3DRESOURCETYPE type = sourceTexture->GetType();
+
+ if(type != destinationTexture->GetType())
+ {
+ return INVALIDCALL();
+ }
+
+ switch(type)
+ {
+ case D3DRTYPE_TEXTURE:
+ {
+ IDirect3DTexture9 *source;
+ IDirect3DTexture9 *dest;
+
+ sourceTexture->QueryInterface(IID_IDirect3DTexture9, (void**)&source);
+ destinationTexture->QueryInterface(IID_IDirect3DTexture9, (void**)&dest);
+
+ ASSERT(source && dest);
+
+ for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++) // FIXME: Fail when source texture has fewer levels than the destination
+ {
+ IDirect3DSurface9 *sourceSurface;
+ IDirect3DSurface9 *destinationSurface;
+
+ source->GetSurfaceLevel(level, &sourceSurface);
+ dest->GetSurfaceLevel(level, &destinationSurface);
+
+ UpdateSurface(sourceSurface, 0, destinationSurface, 0);
+
+ sourceSurface->Release();
+ destinationSurface->Release();
+ }
+
+ source->Release();
+ dest->Release();
+ }
+ break;
+ case D3DRTYPE_VOLUMETEXTURE:
+ {
+ IDirect3DVolumeTexture9 *source;
+ IDirect3DVolumeTexture9 *dest;
+
+ sourceTexture->QueryInterface(IID_IDirect3DVolumeTexture9, (void**)&source);
+ destinationTexture->QueryInterface(IID_IDirect3DVolumeTexture9, (void**)&dest);
+
+ ASSERT(source && dest);
+
+ for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++) // FIXME: Fail when source texture has fewer levels than the destination
+ {
+ IDirect3DVolume9 *sourceVolume;
+ IDirect3DVolume9 *destinationVolume;
+
+ source->GetVolumeLevel(level, &sourceVolume);
+ dest->GetVolumeLevel(level, &destinationVolume);
+
+ updateVolume(sourceVolume, destinationVolume);
+
+ sourceVolume->Release();
+ destinationVolume->Release();
+ }
+
+ source->Release();
+ dest->Release();
+ }
+ break;
+ case D3DRTYPE_CUBETEXTURE:
+ {
+ IDirect3DCubeTexture9 *source;
+ IDirect3DCubeTexture9 *dest;
+
+ sourceTexture->QueryInterface(IID_IDirect3DCubeTexture9, (void**)&source);
+ destinationTexture->QueryInterface(IID_IDirect3DCubeTexture9, (void**)&dest);
+
+ ASSERT(source && dest);
+
+ for(int face = 0; face < 6; face++)
+ {
+ for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++) // FIXME: Fail when source texture has fewer levels than the destination
+ {
+ IDirect3DSurface9 *sourceSurface;
+ IDirect3DSurface9 *destinationSurface;
+
+ source->GetCubeMapSurface((D3DCUBEMAP_FACES)face, level, &sourceSurface);
+ dest->GetCubeMapSurface((D3DCUBEMAP_FACES)face, level, &destinationSurface);
+
+ UpdateSurface(sourceSurface, 0, destinationSurface, 0);
+
+ sourceSurface->Release();
+ destinationSurface->Release();
+ }
+ }
+
+ source->Release();
+ dest->Release();
+ }
+ break;
+ default:
+ UNIMPLEMENTED();
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::ValidateDevice(unsigned long *numPasses)
+ {
+ CriticalSection cs(this);
+
+ TRACE("unsigned long *numPasses = 0x%0.8p", numPasses);
+
+ if(!numPasses)
+ {
+ return INVALIDCALL();
+ }
+
+ *numPasses = 1;
+
+ return D3D_OK;
+ }
+
+ long Direct3DDevice9::getAdapterDisplayMode(unsigned int adapter, D3DDISPLAYMODE *mode)
+ {
+ return d3d9->GetAdapterDisplayMode(adapter, mode);
+ }
+
+ int Direct3DDevice9::typeStride(unsigned char streamType)
+ {
+ static int LUT[] =
+ {
+ 4, // D3DDECLTYPE_FLOAT1 = 0, // 1D float expanded to (value, 0., 0., 1.)
+ 8, // D3DDECLTYPE_FLOAT2 = 1, // 2D float expanded to (value, value, 0., 1.)
+ 12, // D3DDECLTYPE_FLOAT3 = 2, // 3D float expanded to (value, value, value, 1.)
+ 16, // D3DDECLTYPE_FLOAT4 = 3, // 4D float
+ 4, // D3DDECLTYPE_D3DCOLOR = 4, // 4D packed unsigned bytes mapped to 0. to 1. range. Input is in D3DCOLOR format (ARGB) expanded to (R, G, B, A)
+ 4, // D3DDECLTYPE_UBYTE4 = 5, // 4D unsigned byte
+ 4, // D3DDECLTYPE_SHORT2 = 6, // 2D signed short expanded to (value, value, 0., 1.)
+ 8, // D3DDECLTYPE_SHORT4 = 7, // 4D signed short
+ 4, // D3DDECLTYPE_UBYTE4N = 8, // Each of 4 bytes is normalized by dividing to 255.0
+ 4, // D3DDECLTYPE_SHORT2N = 9, // 2D signed short normalized (v[0]/32767.0,v[1]/32767.0,0,1)
+ 8, // D3DDECLTYPE_SHORT4N = 10, // 4D signed short normalized (v[0]/32767.0,v[1]/32767.0,v[2]/32767.0,v[3]/32767.0)
+ 4, // D3DDECLTYPE_USHORT2N = 11, // 2D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,0,1)
+ 8, // D3DDECLTYPE_USHORT4N = 12, // 4D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,v[2]/65535.0,v[3]/65535.0)
+ 4, // D3DDECLTYPE_UDEC3 = 13, // 3D unsigned 10 10 10 format expanded to (value, value, value, 1)
+ 4, // D3DDECLTYPE_DEC3N = 14, // 3D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1)
+ 4, // D3DDECLTYPE_FLOAT16_2 = 15, // Two 16-bit floating point values, expanded to (value, value, 0, 1)
+ 8, // D3DDECLTYPE_FLOAT16_4 = 16, // Four 16-bit floating point values
+ 0, // D3DDECLTYPE_UNUSED = 17, // When the type field in a decl is unused.
+ };
+
+ return LUT[streamType];
+ }
+
+ bool Direct3DDevice9::instanceData()
+ {
+ ASSERT(vertexDeclaration);
+
+ D3DVERTEXELEMENT9 vertexElement[MAXD3DDECLLENGTH + 1];
+ unsigned int numElements;
+ vertexDeclaration->GetDeclaration(vertexElement, &numElements);
+
+ bool instanceData = false;
+
+ for(unsigned int i = 0; i < numElements - 1; i++)
+ {
+ unsigned short stream = vertexElement[i].Stream;
+
+ if(stream != 0)
+ {
+ instanceData = instanceData || (streamSourceFreq[stream] & D3DSTREAMSOURCE_INSTANCEDATA) != 0;
+ }
+ }
+
+ return instanceData;
+ }
+
+ bool Direct3DDevice9::bindResources(Direct3DIndexBuffer9 *indexBuffer)
+ {
+ if(!bindViewport())
+ {
+ return false; // Zero-area target region
+ }
+
+ bindTextures();
+ bindIndexBuffer(indexBuffer);
+ bindShaderConstants();
+ bindLights();
+
+ return true;
+ }
+
+ void Direct3DDevice9::bindVertexStreams(int base, bool instancing, int instance)
+ {
+ ASSERT(vertexDeclaration);
+
+ renderer->resetInputStreams(vertexDeclaration->isPreTransformed());
+
+ D3DVERTEXELEMENT9 vertexElement[MAXD3DDECLLENGTH + 1];
+ unsigned int numElements;
+ vertexDeclaration->GetDeclaration(vertexElement, &numElements);
+
+ // Bind vertex data streams
+ for(unsigned int i = 0; i < numElements - 1; i++)
+ {
+ unsigned short stream = vertexElement[i].Stream;
+ unsigned short offset = vertexElement[i].Offset;
+ unsigned char type = vertexElement[i].Type;
+ unsigned char method = vertexElement[i].Method;
+ unsigned char usage = vertexElement[i].Usage;
+ unsigned char index = vertexElement[i].UsageIndex;
+
+ ASSERT(method == D3DDECLMETHOD_DEFAULT); // FIXME: Unimplemented
+
+ if(!dataStream[stream])
+ {
+ continue;
+ }
+
+ Direct3DVertexBuffer9 *streamBuffer = dataStream[stream];
+ sw::Resource *resource = streamBuffer->getResource();
+ const void *buffer = ((char*)resource->getBuffer() + streamOffset[stream]) + offset;
+
+ int stride = streamStride[stream];
+
+ if(instancing && streamSourceFreq[stream] & D3DSTREAMSOURCE_INSTANCEDATA)
+ {
+ int instanceFrequency = streamSourceFreq[stream] & ~D3DSTREAMSOURCE_INSTANCEDATA;
+ buffer = (char*)buffer + stride * (instance / instanceFrequency);
+
+ stride = 0;
+ }
+ else
+ {
+ buffer = (char*)buffer + stride * base;
+ }
+
+ sw::Stream attribute(resource, buffer, stride);
+
+ switch(type)
+ {
+ case D3DDECLTYPE_FLOAT1: attribute.define(sw::STREAMTYPE_FLOAT, 1, false); break;
+ case D3DDECLTYPE_FLOAT2: attribute.define(sw::STREAMTYPE_FLOAT, 2, false); break;
+ case D3DDECLTYPE_FLOAT3: attribute.define(sw::STREAMTYPE_FLOAT, 3, false); break;
+ case D3DDECLTYPE_FLOAT4: attribute.define(sw::STREAMTYPE_FLOAT, 4, false); break;
+ case D3DDECLTYPE_D3DCOLOR: attribute.define(sw::STREAMTYPE_COLOR, 4, false); break;
+ case D3DDECLTYPE_UBYTE4: attribute.define(sw::STREAMTYPE_BYTE, 4, false); break;
+ case D3DDECLTYPE_SHORT2: attribute.define(sw::STREAMTYPE_SHORT, 2, false); break;
+ case D3DDECLTYPE_SHORT4: attribute.define(sw::STREAMTYPE_SHORT, 4, false); break;
+ case D3DDECLTYPE_UBYTE4N: attribute.define(sw::STREAMTYPE_BYTE, 4, true); break;
+ case D3DDECLTYPE_SHORT2N: attribute.define(sw::STREAMTYPE_SHORT, 2, true); break;
+ case D3DDECLTYPE_SHORT4N: attribute.define(sw::STREAMTYPE_SHORT, 4, true); break;
+ case D3DDECLTYPE_USHORT2N: attribute.define(sw::STREAMTYPE_USHORT, 2, true); break;
+ case D3DDECLTYPE_USHORT4N: attribute.define(sw::STREAMTYPE_USHORT, 4, true); break;
+ case D3DDECLTYPE_UDEC3: attribute.define(sw::STREAMTYPE_UDEC3, 3, false); break;
+ case D3DDECLTYPE_DEC3N: attribute.define(sw::STREAMTYPE_DEC3N, 3, true); break;
+ case D3DDECLTYPE_FLOAT16_2: attribute.define(sw::STREAMTYPE_HALF, 2, false); break;
+ case D3DDECLTYPE_FLOAT16_4: attribute.define(sw::STREAMTYPE_HALF, 4, false); break;
+ case D3DDECLTYPE_UNUSED: attribute.defaults(); break;
+ default:
+ ASSERT(false);
+ }
+
+ if(vertexShader)
+ {
+ const sw::VertexShader *shader = vertexShader->getVertexShader();
+
+ if(!vertexDeclaration->isPreTransformed())
+ {
+ for(int i = 0; i < 16; i++)
+ {
+ if(usage == shader->input[i].usage &&
+ index == shader->input[i].index)
+ {
+ renderer->setInputStream(i, attribute);
+
+ break;
+ }
+ }
+ }
+ else // Bind directly to the output
+ {
+ for(int i = 0; i < 12; i++)
+ {
+ if((usage == shader->output[i][0].usage || (usage == D3DDECLUSAGE_POSITIONT && shader->output[i][0].usage == D3DDECLUSAGE_POSITION)) &&
+ index == shader->output[i][0].index)
+ {
+ renderer->setInputStream(i, attribute);
+
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ switch(usage)
+ {
+ case D3DDECLUSAGE_POSITION: renderer->setInputPositionStream(attribute); break;
+ case D3DDECLUSAGE_BLENDWEIGHT: renderer->setInputBlendWeightStream(attribute); break;
+ case D3DDECLUSAGE_BLENDINDICES: renderer->setInputBlendIndicesStream(attribute.define(sw::STREAMTYPE_INDICES, 1)); break;
+ case D3DDECLUSAGE_NORMAL: renderer->setInputNormalStream(attribute.define(sw::STREAMTYPE_FLOAT, 3)); break;
+ case D3DDECLUSAGE_PSIZE: renderer->setInputPSizeStream(attribute.define(sw::STREAMTYPE_FLOAT, 1)); break;
+ case D3DDECLUSAGE_TEXCOORD: renderer->setInputTexCoordStream(attribute, index); break;
+ case D3DDECLUSAGE_TANGENT: /* Ignored */ break;
+ case D3DDECLUSAGE_BINORMAL: /* Ignored */ break;
+ case D3DDECLUSAGE_TESSFACTOR: UNIMPLEMENTED(); break;
+ case D3DDECLUSAGE_POSITIONT: renderer->setInputPositiontStream(attribute.define(sw::STREAMTYPE_FLOAT, 4)); break;
+ case D3DDECLUSAGE_COLOR: renderer->setInputColorStream(attribute.define(sw::STREAMTYPE_COLOR, 4), index); break;
+ case D3DDECLUSAGE_FOG: /* Ignored */ break;
+ case D3DDECLUSAGE_DEPTH: /* Ignored */ break;
+ case D3DDECLUSAGE_SAMPLE: UNIMPLEMENTED(); break;
+ default:
+ ASSERT(false);
+ }
+ }
+ }
+ }
+
+ void Direct3DDevice9::bindIndexBuffer(Direct3DIndexBuffer9 *indexBuffer)
+ {
+ sw::Resource *resource = 0;
+
+ if(indexBuffer)
+ {
+ resource = indexBuffer->getResource();
+ }
+
+ renderer->setIndexBuffer(resource);
+ }
+
+ void Direct3DDevice9::bindShaderConstants()
+ {
+ if(pixelShaderDirty)
+ {
+ if(pixelShader)
+ {
+ if(pixelShaderConstantsBDirty)
+ {
+ renderer->setPixelShaderConstantB(0, pixelShaderConstantB, pixelShaderConstantsBDirty);
+ }
+
+ if(pixelShaderConstantsFDirty)
+ {
+ renderer->setPixelShaderConstantF(0, pixelShaderConstantF[0], pixelShaderConstantsFDirty);
+ }
+
+ if(pixelShaderConstantsIDirty)
+ {
+ renderer->setPixelShaderConstantI(0, pixelShaderConstantI[0], pixelShaderConstantsIDirty);
+ }
+
+ renderer->setPixelShader(pixelShader->getPixelShader()); // Loads shader constants set with DEF
+ pixelShaderConstantsBDirty = pixelShader->getPixelShader()->dirtyConstantsB; // Shader DEF'ed constants are dirty
+ pixelShaderConstantsFDirty = pixelShader->getPixelShader()->dirtyConstantsF; // Shader DEF'ed constants are dirty
+ pixelShaderConstantsIDirty = pixelShader->getPixelShader()->dirtyConstantsI; // Shader DEF'ed constants are dirty
+ }
+ else
+ {
+ renderer->setPixelShader(0);
+ }
+
+ pixelShaderDirty = false;
+ }
+
+ if(vertexShaderDirty)
+ {
+ if(vertexShader)
+ {
+ if(vertexShaderConstantsBDirty)
+ {
+ renderer->setVertexShaderConstantB(0, vertexShaderConstantB, vertexShaderConstantsBDirty);
+ }
+
+ if(vertexShaderConstantsFDirty)
+ {
+ renderer->setVertexShaderConstantF(0, vertexShaderConstantF[0], vertexShaderConstantsFDirty);
+ }
+
+ if(vertexShaderConstantsIDirty)
+ {
+ renderer->setVertexShaderConstantI(0, vertexShaderConstantI[0], vertexShaderConstantsIDirty);
+ }
+
+ renderer->setVertexShader(vertexShader->getVertexShader()); // Loads shader constants set with DEF
+ vertexShaderConstantsBDirty = vertexShader->getVertexShader()->dirtyConstantsB; // Shader DEF'ed constants are dirty
+ vertexShaderConstantsFDirty = vertexShader->getVertexShader()->dirtyConstantsF; // Shader DEF'ed constants are dirty
+ vertexShaderConstantsIDirty = vertexShader->getVertexShader()->dirtyConstantsI; // Shader DEF'ed constants are dirty
+ }
+ else
+ {
+ renderer->setVertexShader(0);
+ }
+
+ vertexShaderDirty = false;
+ }
+ }
+
+ void Direct3DDevice9::bindLights()
+ {
+ if(!lightsDirty) return;
+
+ Lights::iterator i = light.begin();
+ int active = 0;
+
+ // Set and enable renderer lights
+ while(active < 8)
+ {
+ while(i != light.end() && !i->second.enable)
+ {
+ i++;
+ }
+
+ if(i == light.end())
+ {
+ break;
+ }
+
+ const Light &l = i->second;
+
+ sw::Point position(l.Position.x, l.Position.y, l.Position.z);
+ sw::Color<float> diffuse(l.Diffuse.r, l.Diffuse.g, l.Diffuse.b, l.Diffuse.a);
+ sw::Color<float> specular(l.Specular.r, l.Specular.g, l.Specular.b, l.Specular.a);
+ sw::Color<float> ambient(l.Ambient.r, l.Ambient.g, l.Ambient.b, l.Ambient.a);
+ sw::Vector direction(l.Direction.x, l.Direction.y, l.Direction.z);
+
+ renderer->setLightDiffuse(active, diffuse);
+ renderer->setLightSpecular(active, specular);
+ renderer->setLightAmbient(active, ambient);
+
+ if(l.Type == D3DLIGHT_DIRECTIONAL)
+ {
+ // FIXME: Unsupported, make it a positional light far away without falloff
+ renderer->setLightPosition(active, -1e10f * direction);
+ renderer->setLightRange(active, l.Range);
+ renderer->setLightAttenuation(active, 1, 0, 0);
+ }
+ else if(l.Type == D3DLIGHT_SPOT)
+ {
+ // FIXME: Unsupported, make it a positional light
+ renderer->setLightPosition(active, position);
+ renderer->setLightRange(active, l.Range);
+ renderer->setLightAttenuation(active, l.Attenuation0, l.Attenuation1, l.Attenuation2);
+ }
+ else
+ {
+ renderer->setLightPosition(active, position);
+ renderer->setLightRange(active, l.Range);
+ renderer->setLightAttenuation(active, l.Attenuation0, l.Attenuation1, l.Attenuation2);
+ }
+
+ renderer->setLightEnable(active, true);
+
+ active++;
+ i++;
+ }
+
+ // Remaining lights are disabled
+ while(active < 8)
+ {
+ renderer->setLightEnable(active, false);
+
+ active++;
+ }
+
+ lightsDirty = false;
+ }
+
+ bool Direct3DDevice9::bindViewport()
+ {
+ if(viewport.Width <= 0 || viewport.Height <= 0)
+ {
+ return false;
+ }
+
+ if(scissorEnable)
+ {
+ RECT scissor = scissorRect;
+
+ long viewportLeft = viewport.X;
+ long viewportRight = viewport.X + viewport.Width;
+ long viewportTop = viewport.Y;
+ long viewportBottom = viewport.Y + viewport.Height;
+
+ // Intersection of scissor rectangle and viewport
+ if(viewportLeft > scissor.left) scissor.left = viewportLeft;
+ if(viewportTop > scissor.top) scissor.top = viewportTop;
+ if(viewportRight < scissor.right) scissor.right = viewportRight;
+ if(viewportBottom < scissor.bottom) scissor.bottom = viewportBottom;
+
+ if(scissor.left == scissor.right ||
+ scissor.top == scissor.bottom)
+ {
+ return false;
+ }
+
+ // Dimensions of scissor rectangle relative to viewport
+ float relativeLeft = (float)(scissor.left - viewportLeft) / viewport.Width;
+ float relativeRight = (float)(scissor.right - viewportLeft) / viewport.Width;
+ float relativeTop = (float)(scissor.top - viewportTop) / viewport.Height;
+ float relativeBottom = (float)(scissor.bottom - viewportTop) / viewport.Height;
+
+ // Transformation of clip space coordinates
+ float sX = 1.0f / (relativeRight - relativeLeft); // Scale
+ float tX = sX * ((0.5f - relativeLeft) - (relativeRight - 0.5f)); // Translate
+ float sY = 1.0f / (relativeBottom - relativeTop); // Scale
+ float tY = sY * ((0.5f - relativeTop) - (relativeBottom - 0.5f)); // Translate
+
+ // Set the new viewport
+ sw::Viewport view;
+
+ view.setLeft((float)scissor.left);
+ view.setTop((float)scissor.top);
+ view.setWidth((float)(scissor.right - scissor.left));
+ view.setHeight((float)(scissor.bottom - scissor.top));
+
+ view.setNear(viewport.MinZ);
+ view.setFar(viewport.MaxZ);
+
+ renderer->setViewport(view);
+ renderer->setPostTransformEnable(true);
+ renderer->setPosScale(sX, sY);
+ renderer->setPosOffset(tX, -tY);
+ }
+ else
+ {
+ // Set viewport
+ sw::Viewport view;
+
+ view.setLeft((float)viewport.X);
+ view.setTop((float)viewport.Y);
+ view.setWidth((float)viewport.Width);
+ view.setHeight((float)viewport.Height);
+
+ view.setNear(viewport.MinZ);
+ view.setFar(viewport.MaxZ);
+
+ renderer->setViewport(view);
+ renderer->setPostTransformEnable(false);
+ }
+
+ return true;
+ }
+
+ void Direct3DDevice9::bindTextures()
+ {
+ for(int sampler = 0; sampler < 16 + 4; sampler++)
+ {
+ Direct3DBaseTexture9 *baseTexture = texture[sampler];
+
+ sw::SamplerType type = sampler < 16 ? sw::SAMPLER_PIXEL : sw::SAMPLER_VERTEX;
+ int index = sampler < 16 ? sampler : sampler - 16; // Sampler index within type group
+
+ bool textureUsed = false;
+
+ if(type == sw::SAMPLER_PIXEL && pixelShader)
+ {
+ textureUsed = pixelShader->getPixelShader()->usesSampler(index);
+ }
+ else if(type == sw::SAMPLER_VERTEX && vertexShader)
+ {
+ textureUsed = vertexShader->getVertexShader()->usesSampler(index);
+ }
+ else
+ {
+ textureUsed = true; // FIXME: Check fixed-function use?
+ }
+
+ sw::Resource *resource = 0;
+
+ if(baseTexture && textureUsed)
+ {
+ resource = baseTexture->getResource();
+ }
+
+ renderer->setTextureResource(sampler, resource);
+
+ if(baseTexture && textureUsed)
+ {
+ baseTexture->GenerateMipSubLevels();
+ }
+
+ if(baseTexture && textureUsed)
+ {
+ int levelCount = baseTexture->getInternalLevelCount();
+
+ int textureLOD = baseTexture->GetLOD();
+ int samplerLOD = samplerState[sampler][D3DSAMP_MAXMIPLEVEL];
+ int LOD = textureLOD > samplerLOD ? textureLOD : samplerLOD;
+
+ if(samplerState[sampler][D3DSAMP_MIPFILTER] == D3DTEXF_NONE)
+ {
+ LOD = 0;
+ }
+
+ switch(baseTexture->GetType())
+ {
+ case D3DRTYPE_TEXTURE:
+ {
+ Direct3DTexture9 *texture = dynamic_cast<Direct3DTexture9*>(baseTexture);
+ Direct3DSurface9 *surface;
+
+ for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++)
+ {
+ int surfaceLevel = mipmapLevel;
+
+ if(surfaceLevel < LOD)
+ {
+ surfaceLevel = LOD;
+ }
+
+ if(surfaceLevel < 0)
+ {
+ surfaceLevel = 0;
+ }
+ else if(surfaceLevel >= levelCount)
+ {
+ surfaceLevel = levelCount - 1;
+ }
+
+ surface = texture->getInternalSurfaceLevel(surfaceLevel);
+ renderer->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);
+ }
+ }
+ break;
+ case D3DRTYPE_CUBETEXTURE:
+ for(int face = 0; face < 6; face++)
+ {
+ Direct3DCubeTexture9 *cubeTexture = dynamic_cast<Direct3DCubeTexture9*>(baseTexture);
+ Direct3DSurface9 *surface;
+
+ for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++)
+ {
+ int surfaceLevel = mipmapLevel;
+
+ if(surfaceLevel < LOD)
+ {
+ surfaceLevel = LOD;
+ }
+
+ if(surfaceLevel < 0)
+ {
+ surfaceLevel = 0;
+ }
+ else if(surfaceLevel >= levelCount)
+ {
+ surfaceLevel = levelCount - 1;
+ }
+
+ surface = cubeTexture->getInternalCubeMapSurface((D3DCUBEMAP_FACES)face, surfaceLevel);
+ renderer->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
+ }
+ }
+ break;
+ case D3DRTYPE_VOLUMETEXTURE:
+ {
+ Direct3DVolumeTexture9 *volumeTexture = dynamic_cast<Direct3DVolumeTexture9*>(baseTexture);
+ Direct3DVolume9 *volume;
+
+ for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++)
+ {
+ int surfaceLevel = mipmapLevel;
+
+ if(surfaceLevel < LOD)
+ {
+ surfaceLevel = LOD;
+ }
+
+ if(surfaceLevel < 0)
+ {
+ surfaceLevel = 0;
+ }
+ else if(surfaceLevel >= levelCount)
+ {
+ surfaceLevel = levelCount - 1;
+ }
+
+ volume = volumeTexture->getInternalVolumeLevel(surfaceLevel);
+ renderer->setTextureLevel(sampler, 0, mipmapLevel, volume, sw::TEXTURE_3D);
+ }
+ }
+ break;
+ default:
+ UNIMPLEMENTED();
+ }
+ }
+ else
+ {
+ renderer->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
+ }
+ }
+ }
+
+ bool Direct3DDevice9::isRecording() const
+ {
+ return stateRecorder != 0;
+ }
+
+ void Direct3DDevice9::setOcclusionEnabled(bool enable)
+ {
+ renderer->setOcclusionEnabled(enable);
+ }
+
+ void Direct3DDevice9::removeQuery(sw::Query *query)
+ {
+ renderer->removeQuery(query);
+ }
+
+ void Direct3DDevice9::addQuery(sw::Query *query)
+ {
+ renderer->addQuery(query);
+ }
+
+ void Direct3DDevice9::stretchRect(Direct3DSurface9 *source, const RECT *sourceRect, Direct3DSurface9 *dest, const RECT *destRect, D3DTEXTUREFILTERTYPE filter)
+ {
+ D3DSURFACE_DESC sourceDescription;
+ D3DSURFACE_DESC destDescription;
+
+ source->GetDesc(&sourceDescription);
+ dest->GetDesc(&destDescription);
+
+ int sWidth = source->getExternalWidth();
+ int sHeight = source->getExternalHeight();
+ int dWidth = dest->getExternalWidth();
+ int dHeight = dest->getExternalHeight();
+
+ sw::Rect sRect = {0};
+ sw::Rect dRect = {0};
+
+ if(sourceRect)
+ {
+ sRect.left = sourceRect->left;
+ sRect.top = sourceRect->top;
+ sRect.right = sourceRect->right;
+ sRect.bottom = sourceRect->bottom;
+ }
+ else
+ {
+ sRect.top = 0;
+ sRect.left = 0;
+ sRect.bottom = sHeight;
+ sRect.right = sWidth;
+ }
+
+ if(destRect)
+ {
+ dRect.left = destRect->left;
+ dRect.top = destRect->top;
+ dRect.right = destRect->right;
+ dRect.bottom = destRect->bottom;
+ }
+ else
+ {
+ dRect.top = 0;
+ dRect.left = 0;
+ dRect.bottom = dHeight;
+ dRect.right = dWidth;
+ }
+
+ bool scaling = (sRect.right - sRect.left != dRect.right - dRect.left) || (sRect.bottom - sRect.top != dRect.bottom - dRect.top);
+ bool equalFormats = source->getInternalFormat() == dest->getInternalFormat();
+ bool depthStencil = (sourceDescription.Usage & D3DUSAGE_DEPTHSTENCIL) == D3DUSAGE_DEPTHSTENCIL;
+ bool alpha0xFF = false;
+
+ if((sourceDescription.Format == D3DFMT_A8R8G8B8 && destDescription.Format == D3DFMT_X8R8G8B8) ||
+ (sourceDescription.Format == D3DFMT_X8R8G8B8 && destDescription.Format == D3DFMT_A8R8G8B8))
+ {
+ equalFormats = true;
+ alpha0xFF = true;
+ }
+
+ if(depthStencil) // Copy entirely, internally // FIXME: Check
+ {
+ if(source->hasDepth())
+ {
+ byte *sourceBuffer = (byte*)source->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
+ byte *destBuffer = (byte*)dest->lockInternal(0, 0, 0, sw::LOCK_DISCARD, sw::PUBLIC);
+
+ unsigned int width = source->getInternalWidth();
+ unsigned int height = source->getInternalHeight();
+ unsigned int pitch = source->getInternalPitchB();
+
+ for(unsigned int y = 0; y < height; y++)
+ {
+ memcpy(destBuffer, sourceBuffer, pitch); // FIXME: Only copy width * bytes
+
+ sourceBuffer += pitch;
+ destBuffer += pitch;
+ }
+
+ source->unlockInternal();
+ dest->unlockInternal();
+ }
+
+ if(source->hasStencil())
+ {
+ byte *sourceBuffer = (byte*)source->lockStencil(0, sw::PUBLIC);
+ byte *destBuffer = (byte*)dest->lockStencil(0, sw::PUBLIC);
+
+ unsigned int width = source->getInternalWidth();
+ unsigned int height = source->getInternalHeight();
+ unsigned int pitch = source->getStencilPitchB();
+
+ for(unsigned int y = 0; y < height; y++)
+ {
+ memcpy(destBuffer, sourceBuffer, pitch); // FIXME: Only copy width * bytes
+
+ sourceBuffer += pitch;
+ destBuffer += pitch;
+ }
+
+ source->unlockStencil();
+ dest->unlockStencil();
+ }
+ }
+ else if(!scaling && equalFormats)
+ {
+ unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.left, sRect.top, 0, sw::LOCK_READONLY, sw::PUBLIC);
+ unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.left, dRect.top, 0, sw::LOCK_READWRITE, sw::PUBLIC);
+ unsigned int sourcePitch = source->getInternalPitchB();
+ unsigned int destPitch = dest->getInternalPitchB();
+
+ unsigned int width = dRect.right - dRect.left;
+ unsigned int height = dRect.bottom - dRect.top;
+ unsigned int bytes = width * sw::Surface::bytes(source->getInternalFormat());
+
+ for(unsigned int y = 0; y < height; y++)
+ {
+ memcpy(destBytes, sourceBytes, bytes);
+
+ if(alpha0xFF)
+ {
+ for(unsigned int x = 0; x < width; x++)
+ {
+ destBytes[4 * x + 3] = 0xFF;
+ }
+ }
+
+ sourceBytes += sourcePitch;
+ destBytes += destPitch;
+ }
+
+ source->unlockInternal();
+ dest->unlockInternal();
+ }
+ else
+ {
+ renderer->blit(source, sRect, dest, dRect, filter >= D3DTEXF_LINEAR);
+ }
+ }
+
+ long Direct3DDevice9::updateVolume(IDirect3DVolume9 *sourceVolume, IDirect3DVolume9 *destinationVolume)
+ {
+ TRACE("IDirect3DVolume9 *sourceVolume = 0x%0.8p, IDirect3DVolume9 *destinationVolume = 0x%0.8p", sourceVolume, destinationVolume);
+
+ if(!sourceVolume || !destinationVolume)
+ {
+ return INVALIDCALL();
+ }
+
+ D3DVOLUME_DESC sourceDescription;
+ D3DVOLUME_DESC destinationDescription;
+
+ sourceVolume->GetDesc(&sourceDescription);
+ destinationVolume->GetDesc(&destinationDescription);
+
+ if(sourceDescription.Pool != D3DPOOL_SYSTEMMEM ||
+ destinationDescription.Pool != D3DPOOL_DEFAULT ||
+ sourceDescription.Format != destinationDescription.Format ||
+ sourceDescription.Width != destinationDescription.Width ||
+ sourceDescription.Height != destinationDescription.Height ||
+ sourceDescription.Depth != destinationDescription.Depth)
+ {
+ return INVALIDCALL();
+ }
+
+ sw::Surface *source = static_cast<Direct3DVolume9*>(sourceVolume);
+ sw::Surface *dest = static_cast<Direct3DVolume9*>(destinationVolume);
+
+ if(source->getExternalPitchB() != dest->getExternalPitchB() ||
+ source->getExternalSliceB() != dest->getExternalSliceB())
+ {
+ UNIMPLEMENTED();
+ }
+
+ void *sBuffer = source->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
+ void *dBuffer = dest->lockExternal(0, 0, 0, sw::LOCK_WRITEONLY, sw::PUBLIC);
+
+ memcpy(dBuffer, sBuffer, source->getExternalSliceB() * sourceDescription.Depth);
+
+ source->unlockExternal();
+ dest->unlockExternal();
+
+ return D3D_OK;
+ }
+
+ bool Direct3DDevice9::validRectangle(const RECT *rect, IDirect3DSurface9 *surface)
+ {
+ if(!rect)
+ {
+ return true;
+ }
+
+ if(rect->right <= rect->left || rect->bottom <= rect->top)
+ {
+ return false;
+ }
+
+ if(rect->left < 0 || rect->top < 0)
+ {
+ return false;
+ }
+
+ D3DSURFACE_DESC description;
+ surface->GetDesc(&description);
+
+ if(rect->right > (int)description.Width || rect->bottom > (int)description.Height)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ void Direct3DDevice9::configureFPU()
+ {
+ // _controlfp(_PC_24, _MCW_PC); // Single-precision
+ _controlfp(_MCW_EM, _MCW_EM); // Mask all exceptions
+ _controlfp(_RC_NEAR, _MCW_RC); // Round to nearest
+ }
+}
diff --git a/src/D3D9/Direct3DDevice9.hpp b/src/D3D9/Direct3DDevice9.hpp
new file mode 100644
index 0000000..0750f62
--- /dev/null
+++ b/src/D3D9/Direct3DDevice9.hpp
@@ -0,0 +1,337 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Direct3DDevice9_hpp
+#define D3D9_Direct3DDevice9_hpp
+
+#include "Unknown.hpp"
+
+#include "Direct3D9.hpp"
+#include "Direct3DSwapChain9.hpp"
+
+#include "Stream.hpp"
+
+#include <d3d9.h>
+#include <map>
+#include <list>
+
+namespace sw
+{
+ class Renderer;
+ class Context;
+ struct Query;
+}
+
+namespace D3D9
+{
+ class Direct3DVertexDeclaration9;
+ class Direct3DStateBlock9;
+ class Direct3DSurface9;
+ class Direct3DPixelShader9;
+ class Direct3DVertexShader9;
+ class irect3DVertexDeclaration9;
+ class Direct3DVertexBuffer9;
+ class Direct3DIndexBuffer9;
+ class CriticalSection;
+
+ class Direct3DDevice9 : public IDirect3DDevice9, public Unknown
+ {
+ friend CriticalSection;
+ friend Direct3DSwapChain9;
+
+ public:
+ Direct3DDevice9(const HINSTANCE instance, Direct3D9 *d3d9, unsigned int adapter, D3DDEVTYPE deviceType, HWND focusWindow, unsigned long behaviourFlags, D3DPRESENT_PARAMETERS *presentParameters);
+
+ virtual ~Direct3DDevice9();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // IDirect3DDevice9 methods
+ long __stdcall BeginScene();
+ long __stdcall BeginStateBlock();
+ long __stdcall Clear(unsigned long count, const D3DRECT *rects, unsigned long flags, unsigned long color, float z, unsigned long stencil);
+ long __stdcall ColorFill(IDirect3DSurface9 *surface, const RECT *rect, D3DCOLOR color);
+ long __stdcall CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS *presentParameters, IDirect3DSwapChain9 **swapChain);
+ long __stdcall CreateCubeTexture(unsigned int edgeLength, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DCubeTexture9 **cubeTexture, void **sharedHandle);
+ long __stdcall CreateDepthStencilSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, unsigned long multiSampleQuality, int discard, IDirect3DSurface9 **surface, void **sharedHandle);
+ long __stdcall CreateIndexBuffer(unsigned int length, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer9 **indexBuffer, void **sharedHandle);
+ long __stdcall CreateOffscreenPlainSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DPOOL pool, IDirect3DSurface9 **surface, void **sharedHandle);
+ long __stdcall CreatePixelShader(const unsigned long *function, IDirect3DPixelShader9 **shader);
+ long __stdcall CreateQuery(D3DQUERYTYPE type, IDirect3DQuery9 **query);
+ long __stdcall CreateRenderTarget(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, unsigned long multiSampleQuality, int lockable, IDirect3DSurface9 **surface, void **sharedHandle);
+ long __stdcall CreateStateBlock(D3DSTATEBLOCKTYPE type, IDirect3DStateBlock9 **stateBlock);
+ long __stdcall CreateTexture(unsigned int width, unsigned int height, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DTexture9 **texture, void **sharedHandle);
+ long __stdcall CreateVertexBuffer(unsigned int length, unsigned long usage, unsigned long FVF, D3DPOOL pool, IDirect3DVertexBuffer9 **vertexBuffer, void **sharedHandle);
+ long __stdcall CreateVertexDeclaration(const D3DVERTEXELEMENT9 *vertexElements, IDirect3DVertexDeclaration9 **declaration);
+ long __stdcall CreateVertexShader(const unsigned long *function, IDirect3DVertexShader9 **shader);
+ long __stdcall CreateVolumeTexture(unsigned int width, unsigned int height, unsigned int depth, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DVolumeTexture9 **volumeTexture, void **sharedHandle);
+ long __stdcall DeletePatch(unsigned int handle);
+ long __stdcall DrawIndexedPrimitive(D3DPRIMITIVETYPE type, int baseVertexIndex, unsigned int minIndex, unsigned int numVertices, unsigned int startIndex, unsigned int primitiveCount);
+ long __stdcall DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE type, unsigned int minVertexIndex, unsigned int numVertexIndices, unsigned int PrimitiveCount, const void *indexData, D3DFORMAT indexDataFormat, const void *vertexStreamZeroData, unsigned int VertexStreamZeroStride);
+ long __stdcall DrawPrimitive(D3DPRIMITIVETYPE primitiveType, unsigned int startVertex, unsigned int primiveCount);
+ long __stdcall DrawPrimitiveUP(D3DPRIMITIVETYPE primitiveType, unsigned int primitiveCount, const void *vertexStreamZeroData, unsigned int vertexStreamZeroStride);
+ long __stdcall DrawRectPatch(unsigned int handle, const float *numSegs, const D3DRECTPATCH_INFO *rectPatchInfo);
+ long __stdcall DrawTriPatch(unsigned int handle, const float *numSegs, const D3DTRIPATCH_INFO *triPatchInfo);
+ long __stdcall EndScene();
+ long __stdcall EndStateBlock(IDirect3DStateBlock9 **stateBlock);
+ long __stdcall EvictManagedResources();
+ unsigned int __stdcall GetAvailableTextureMem();
+ long __stdcall GetBackBuffer(unsigned int swapChain, unsigned int index, D3DBACKBUFFER_TYPE type, IDirect3DSurface9 **backBuffer);
+ long __stdcall GetClipPlane(unsigned long index, float *plane);
+ long __stdcall GetClipStatus(D3DCLIPSTATUS9 *clipStatus);
+ long __stdcall GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS *parameters);
+ long __stdcall GetCurrentTexturePalette(unsigned int *paletteNumber);
+ long __stdcall GetDepthStencilSurface(IDirect3DSurface9 **depthStencilSurface);
+ long __stdcall GetDeviceCaps(D3DCAPS9 *caps);
+ long __stdcall GetDirect3D(IDirect3D9 **D3D);
+ long __stdcall GetDisplayMode(unsigned int swapChain ,D3DDISPLAYMODE *mode);
+ long __stdcall GetFrontBufferData(unsigned int swapChain, IDirect3DSurface9 *destSurface);
+ long __stdcall GetFVF(unsigned long *FVF);
+ void __stdcall GetGammaRamp(unsigned int swapChain, D3DGAMMARAMP *ramp);
+ long __stdcall GetIndices(IDirect3DIndexBuffer9 **indexData);
+ long __stdcall GetLight(unsigned long index, D3DLIGHT9 *p);
+ long __stdcall GetLightEnable(unsigned long index , int *enable);
+ long __stdcall GetMaterial(D3DMATERIAL9 *material);
+ float __stdcall GetNPatchMode();
+ unsigned int __stdcall GetNumberOfSwapChains();
+ long __stdcall GetPaletteEntries(unsigned int paletteNumber, PALETTEENTRY *entries);
+ long __stdcall GetPixelShader(IDirect3DPixelShader9 **shader);
+ long __stdcall GetPixelShaderConstantB(unsigned int startRegister, int *constantData, unsigned int count);
+ long __stdcall GetPixelShaderConstantF(unsigned int startRegister, float *constantData, unsigned int count);
+ long __stdcall GetPixelShaderConstantI(unsigned int startRegister, int *constantData, unsigned int count);
+ long __stdcall GetRasterStatus(unsigned int swapChain, D3DRASTER_STATUS *rasterStatus);
+ long __stdcall GetRenderState(D3DRENDERSTATETYPE State, unsigned long *value);
+ long __stdcall GetRenderTarget(unsigned long index, IDirect3DSurface9 **renderTarget);
+ long __stdcall GetRenderTargetData(IDirect3DSurface9 *renderTarget, IDirect3DSurface9 *destSurface);
+ long __stdcall GetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE type, unsigned long *value);
+ long __stdcall GetScissorRect(RECT *rect);
+ int __stdcall GetSoftwareVertexProcessing();
+ long __stdcall GetStreamSource(unsigned int streamNumber, IDirect3DVertexBuffer9 **streamData, unsigned int *offset, unsigned int *stride);
+ long __stdcall GetStreamSourceFreq(unsigned int streamNumber, unsigned int *divider);
+ long __stdcall GetSwapChain(unsigned int index, IDirect3DSwapChain9 **swapChain);
+ long __stdcall GetTexture(unsigned long sampler, IDirect3DBaseTexture9 **texture);
+ long __stdcall GetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long *value);
+ long __stdcall GetTransform(D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix);
+ long __stdcall GetVertexDeclaration(IDirect3DVertexDeclaration9 **declaration);
+ long __stdcall GetVertexShader(IDirect3DVertexShader9 **shader);
+ long __stdcall GetVertexShaderConstantB(unsigned int startRegister, int *constantData, unsigned int count);
+ long __stdcall GetVertexShaderConstantF(unsigned int startRegister, float *constantData, unsigned int count);
+ long __stdcall GetVertexShaderConstantI(unsigned int startRegister, int *constantData, unsigned int count);
+ long __stdcall GetViewport(D3DVIEWPORT9 *viewport);
+ long __stdcall LightEnable(unsigned long index, int enable);
+ long __stdcall MultiplyTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix);
+ long __stdcall Present(const RECT *sourceRect, const RECT *destRect, HWND destWindowOverride, const RGNDATA *dirtyRegion);
+ long __stdcall ProcessVertices(unsigned int srcStartIndex, unsigned int destIndex, unsigned int vertexCount, IDirect3DVertexBuffer9 *destBuffer, IDirect3DVertexDeclaration9 *vertexDeclaration, unsigned long flags);
+ long __stdcall Reset(D3DPRESENT_PARAMETERS *presentParameters);
+ long __stdcall SetClipPlane(unsigned long index, const float *plane);
+ long __stdcall SetClipStatus(const D3DCLIPSTATUS9 *clipStatus);
+ long __stdcall SetCurrentTexturePalette(unsigned int paletteNumber);
+ void __stdcall SetCursorPosition(int x, int y, unsigned long flags);
+ long __stdcall SetCursorProperties(unsigned int x, unsigned int y, IDirect3DSurface9 *cursorBitmap);
+ long __stdcall SetDepthStencilSurface(IDirect3DSurface9 *newDepthStencil);
+ long __stdcall SetDialogBoxMode(int enableDialogs);
+ long __stdcall SetFVF(unsigned long FVF);
+ void __stdcall SetGammaRamp(unsigned int swapChain, unsigned long flags, const D3DGAMMARAMP *ramp);
+ long __stdcall SetIndices(IDirect3DIndexBuffer9 *indexData);
+ long __stdcall SetLight(unsigned long index, const D3DLIGHT9 *light);
+ long __stdcall SetMaterial(const D3DMATERIAL9 *material);
+ long __stdcall SetNPatchMode(float segments);
+ long __stdcall SetPaletteEntries(unsigned int paletteNumber, const PALETTEENTRY *entries);
+ long __stdcall SetPixelShader(IDirect3DPixelShader9 *shader);
+ long __stdcall SetPixelShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count);
+ long __stdcall SetPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
+ long __stdcall SetPixelShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count);
+ long __stdcall SetRenderState(D3DRENDERSTATETYPE state, unsigned long value);
+ long __stdcall SetRenderTarget(unsigned long index, IDirect3DSurface9 *renderTarget);
+ long __stdcall SetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE state, unsigned long value);
+ long __stdcall SetScissorRect(const RECT *rect);
+ long __stdcall SetSoftwareVertexProcessing(int software);
+ long __stdcall SetStreamSource(unsigned int stream, IDirect3DVertexBuffer9 *data, unsigned int offset, unsigned int stride);
+ long __stdcall SetStreamSourceFreq(unsigned int streamNumber, unsigned int divider);
+ long __stdcall SetTexture(unsigned long sampler, IDirect3DBaseTexture9 *texture);
+ long __stdcall SetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long value);
+ long __stdcall SetTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix);
+ long __stdcall SetVertexDeclaration(IDirect3DVertexDeclaration9 *declaration);
+ long __stdcall SetVertexShader(IDirect3DVertexShader9 *shader);
+ long __stdcall SetVertexShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count);
+ long __stdcall SetVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
+ long __stdcall SetVertexShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count);
+ long __stdcall SetViewport(const D3DVIEWPORT9 *viewport);
+ int __stdcall ShowCursor(int show);
+ long __stdcall StretchRect(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destSurface, const RECT *destRect, D3DTEXTUREFILTERTYPE filter);
+ long __stdcall TestCooperativeLevel();
+ long __stdcall UpdateSurface(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destinationSurface, const POINT *destPoint);
+ long __stdcall UpdateTexture(IDirect3DBaseTexture9 *sourceTexture, IDirect3DBaseTexture9 *destinationTexture);
+ long __stdcall ValidateDevice(unsigned long *numPasses);
+
+ // Internal methods
+ long getAdapterDisplayMode(unsigned int adapter, D3DDISPLAYMODE *mode);
+ bool isRecording() const; // In a state recording mode
+ void setOcclusionEnabled(bool enable);
+ void removeQuery(sw::Query *query);
+ void addQuery(sw::Query *query);
+ void stretchRect(Direct3DSurface9 *sourceSurface, const RECT *sourceRect, Direct3DSurface9 *destSurface, const RECT *destRect, D3DTEXTUREFILTERTYPE filter);
+
+ private:
+ static int typeStride(unsigned char streamType);
+ bool instanceData();
+ bool bindResources(Direct3DIndexBuffer9 *indexBuffer);
+ void bindVertexStreams(int base, bool instancing, int instance);
+ void bindIndexBuffer(Direct3DIndexBuffer9 *indexBuffer);
+ void bindShaderConstants();
+ void bindLights();
+ bool bindViewport(); // Also adjusts for scissoring
+ void bindTextures();
+
+ long updateVolume(IDirect3DVolume9 *sourceVolume, IDirect3DVolume9 *destinationVolume);
+ bool validRectangle(const RECT *rect, IDirect3DSurface9 *surface);
+ void configureFPU();
+
+ // Creation parameters
+ const HINSTANCE instance;
+ Direct3D9 *d3d9;
+ const unsigned int adapter;
+ const D3DDEVTYPE deviceType;
+ const HWND focusWindow;
+ const unsigned long behaviourFlags;
+
+ HWND deviceWindow;
+
+ D3DVIEWPORT9 viewport;
+ D3DMATRIX matrix[512];
+ Direct3DBaseTexture9 *texture[16 + 4];
+ D3DMATERIAL9 material;
+ float plane[6][4];
+ D3DCLIPSTATUS9 clipStatus;
+ RECT scissorRect;
+ bool scissorEnable;
+
+ struct Light : D3DLIGHT9
+ {
+ Light &operator=(const D3DLIGHT9 &light)
+ {
+ Type = light.Type;
+ Diffuse = light.Diffuse;
+ Specular = light.Specular;
+ Ambient = light.Ambient;
+ Position = light.Position;
+ Direction = light.Direction;
+ Range = light.Range;
+ Falloff = light.Falloff;
+ Attenuation0 = light.Attenuation0;
+ Attenuation1 = light.Attenuation1;
+ Attenuation2 = light.Attenuation2;
+ Theta = light.Theta;
+ Phi = light.Phi;
+
+ return *this;
+ }
+
+ bool enable;
+ };
+
+ struct Lights : std::map<int, Light>
+ {
+ bool exists(int index)
+ {
+ return find(index) != end();
+ }
+ };
+
+ Lights light;
+ bool softwareVertexProcessing;
+ Direct3DPixelShader9 *pixelShader;
+ Direct3DVertexShader9 *vertexShader;
+
+ bool lightsDirty;
+ bool pixelShaderDirty;
+ int pixelShaderConstantsBDirty;
+ int pixelShaderConstantsFDirty;
+ int pixelShaderConstantsIDirty;
+ bool vertexShaderDirty;
+ int vertexShaderConstantsBDirty;
+ int vertexShaderConstantsFDirty;
+ int vertexShaderConstantsIDirty;
+
+ float pixelShaderConstantF[224][4];
+ int pixelShaderConstantI[16][4];
+ int pixelShaderConstantB[16];
+
+ float vertexShaderConstantF[256][4];
+ int vertexShaderConstantI[16][4];
+ int vertexShaderConstantB[16];
+
+ Direct3DVertexDeclaration9 *vertexDeclaration;
+ Direct3DVertexBuffer9 *dataStream[16];
+ int streamStride[16];
+ int streamOffset[16];
+ unsigned int streamSourceFreq[16];
+ Direct3DIndexBuffer9 *indexData;
+
+ Direct3DSwapChain9 *swapChain;
+ Direct3DSurface9 *renderTarget[4];
+ Direct3DSurface9 *depthStencil;
+ Direct3DSurface9 *autoDepthStencil;
+
+ Direct3DStateBlock9 *stateRecorder;
+
+ unsigned long renderState[D3DRS_BLENDOPALPHA + 1];
+ unsigned long textureStageState[8][D3DTSS_CONSTANT + 1];
+ unsigned long samplerState[16 + 4][D3DSAMP_DMAPOFFSET + 1];
+ bool init;
+
+ struct Palette
+ {
+ PALETTEENTRY entry[256];
+ };
+
+ unsigned int currentPalette;
+ std::map<int, Palette> palette;
+
+ sw::Context *context;
+ sw::Renderer *renderer;
+
+ bool instancingEnabled;
+
+ sw::Surface *cursor;
+ bool showCursor;
+
+ CRITICAL_SECTION criticalSection;
+ };
+
+ class CriticalSection
+ {
+ public:
+ CriticalSection(Direct3DDevice9 *device) : device(device)
+ {
+ if(device->behaviourFlags & D3DCREATE_MULTITHREADED)
+ {
+ EnterCriticalSection(&device->criticalSection);
+ }
+ }
+
+ ~CriticalSection()
+ {
+ if(device->behaviourFlags & D3DCREATE_MULTITHREADED)
+ {
+ LeaveCriticalSection(&device->criticalSection);
+ }
+ }
+
+ private:
+ Direct3DDevice9 *const device;
+ };
+}
+
+#endif // D3D9_Direct3DDevice9_hpp
diff --git a/src/D3D9/Direct3DDevice9Ex.cpp b/src/D3D9/Direct3DDevice9Ex.cpp
new file mode 100644
index 0000000..9f4b3ba
--- /dev/null
+++ b/src/D3D9/Direct3DDevice9Ex.cpp
@@ -0,0 +1,1039 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3DDevice9Ex.hpp"
+
+#include "Direct3D9Ex.hpp"
+#include "Direct3DSurface9.hpp"
+#include "Direct3DIndexBuffer9.hpp"
+#include "Direct3DVertexBuffer9.hpp"
+#include "Direct3DTexture9.hpp"
+#include "Direct3DVolumeTexture9.hpp"
+#include "Direct3DCubeTexture9.hpp"
+#include "Direct3DVertexDeclaration9.hpp"
+#include "Direct3DSwapChain9.hpp"
+#include "Direct3DPixelShader9.hpp"
+#include "Direct3DVertexShader9.hpp"
+#include "Direct3DStateBlock9.hpp"
+#include "Direct3DQuery9.hpp"
+#include "Direct3DVolume9.hpp"
+
+#include "Debug.hpp"
+#include "Renderer.hpp"
+#include "FrameBuffer.hpp"
+#include "Clipper.hpp"
+#include "Configurator.hpp"
+#include "Timer.hpp"
+
+#include <assert.h>
+
+namespace D3D9
+{
+ inline unsigned long FtoDW(float f)
+ {
+ return (unsigned long&)f;
+ }
+
+ inline float DWtoF(unsigned long dw)
+ {
+ return (float&)dw;
+ }
+
+ Direct3DDevice9Ex::Direct3DDevice9Ex(const HINSTANCE instance, Direct3D9Ex *d3d9ex, unsigned int adapter, D3DDEVTYPE deviceType, HWND focusWindow, unsigned long behaviourFlags, D3DPRESENT_PARAMETERS *presentParameters) : Direct3DDevice9(instance, d3d9ex, adapter, deviceType, focusWindow, behaviourFlags, presentParameters), d3d9ex(d3d9ex)
+ {
+ }
+
+ Direct3DDevice9Ex::~Direct3DDevice9Ex()
+ {
+ }
+
+ long Direct3DDevice9Ex::QueryInterface(const IID &iid, void **object)
+ {
+ CriticalSection cs(this);
+
+ TRACE("const IID &iid = 0x%0.8p, void **object = 0x%0.8p", iid, object);
+
+ if(iid == IID_IDirect3DDevice9Ex ||
+ iid == IID_IDirect3DDevice9 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long Direct3DDevice9Ex::AddRef()
+ {
+ TRACE("void");
+
+ return Direct3DDevice9::AddRef();
+ }
+
+ unsigned long Direct3DDevice9Ex::Release()
+ {
+ TRACE("void");
+
+ return Direct3DDevice9::Release();
+ }
+
+ long Direct3DDevice9Ex::BeginScene()
+ {
+ TRACE("void");
+
+ return Direct3DDevice9::BeginScene();
+ }
+
+ long Direct3DDevice9Ex::BeginStateBlock()
+ {
+ TRACE("void");
+
+ return Direct3DDevice9::BeginStateBlock();
+ }
+
+ long Direct3DDevice9Ex::Clear(unsigned long count, const D3DRECT *rects, unsigned long flags, unsigned long color, float z, unsigned long stencil)
+ {
+ TRACE("unsigned long count = %d, const D3DRECT *rects = 0x%0.8p, unsigned long flags = 0x%0.8X, unsigned long color = 0x%0.8X, float z = %f, unsigned long stencil = %d", count, rects, flags, color, z, stencil);
+
+ return Direct3DDevice9::Clear(count, rects, flags, color, z, stencil);
+ }
+
+ long Direct3DDevice9Ex::ColorFill(IDirect3DSurface9 *surface, const RECT *rect, D3DCOLOR color)
+ {
+ TRACE("IDirect3DSurface9 *surface = 0x%0.8p, const RECT *rect = 0x%0.8p, D3DCOLOR color = 0x%0.8X", surface, rect, color);
+
+ return Direct3DDevice9::ColorFill(surface, rect, color);
+ }
+
+ long Direct3DDevice9Ex::CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS *presentParameters, IDirect3DSwapChain9 **swapChain)
+ {
+ TRACE("D3DPRESENT_PARAMETERS *presentParameters = 0x%0.8p, IDirect3DSwapChain9 **swapChain = 0x%0.8p", presentParameters, swapChain);
+
+ return Direct3DDevice9::CreateAdditionalSwapChain(presentParameters, swapChain);
+ }
+
+ long Direct3DDevice9Ex::CreateCubeTexture(unsigned int edgeLength, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DCubeTexture9 **cubeTexture, void **sharedHandle)
+ {
+ TRACE("unsigned int edgeLength = %d, unsigned int levels = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DCubeTexture9 **cubeTexture = 0x%0.8p, void **sharedHandle = 0x%0.8p", edgeLength, levels, usage, format, pool, cubeTexture, sharedHandle);
+
+ return Direct3DDevice9::CreateCubeTexture(edgeLength, levels, usage, format, pool, cubeTexture, sharedHandle);
+ }
+
+ long Direct3DDevice9Ex::CreateDepthStencilSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, unsigned long multiSampleQuality, int discard, IDirect3DSurface9 **surface, void **sharedHandle)
+ {
+ TRACE("unsigned int width = %d, unsigned int height = %d, D3DFORMAT format = %d, D3DMULTISAMPLE_TYPE multiSample = %d, unsigned long multiSampleQuality = %d, int discard = %d, IDirect3DSurface9 **surface = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, format, multiSample, multiSampleQuality, discard, surface, sharedHandle);
+
+ return Direct3DDevice9::CreateDepthStencilSurface(width, height, format, multiSample, multiSampleQuality, discard, surface, sharedHandle);
+ }
+
+ long Direct3DDevice9Ex::CreateIndexBuffer(unsigned int length, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer9 **indexBuffer, void **sharedHandle)
+ {
+ TRACE("unsigned int length = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DIndexBuffer9 **indexBuffer = 0x%0.8p, void **sharedHandle = 0x%0.8p", length, usage, format, pool, indexBuffer, sharedHandle);
+
+ return Direct3DDevice9::CreateIndexBuffer(length, usage, format, pool, indexBuffer, sharedHandle);
+ }
+
+ long Direct3DDevice9Ex::CreateOffscreenPlainSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DPOOL pool, IDirect3DSurface9 **surface, void **sharedHandle)
+ {
+ TRACE("unsigned int width = %d, unsigned int height = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DSurface9 **surface = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, format, pool, surface, sharedHandle);
+
+ return Direct3DDevice9::CreateOffscreenPlainSurface(width, height, format, pool, surface, sharedHandle);
+ }
+
+ long Direct3DDevice9Ex::CreatePixelShader(const unsigned long *function, IDirect3DPixelShader9 **shader)
+ {
+ TRACE("const unsigned long *function = 0x%0.8p, IDirect3DPixelShader9 **shader = 0x%0.8p", function, shader);
+
+ return Direct3DDevice9::CreatePixelShader(function, shader);
+ }
+
+ long Direct3DDevice9Ex::CreateQuery(D3DQUERYTYPE type, IDirect3DQuery9 **query)
+ {
+ TRACE("D3DQUERYTYPE type = %d, IDirect3DQuery9 **query = 0x%0.8p", type, query);
+
+ return Direct3DDevice9::CreateQuery(type, query);
+ }
+
+ long Direct3DDevice9Ex::CreateRenderTarget(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, unsigned long multiSampleQuality, int lockable, IDirect3DSurface9 **surface, void **sharedHandle)
+ {
+ TRACE("unsigned int width = %d, unsigned int height = %d, D3DFORMAT format = %d, D3DMULTISAMPLE_TYPE multiSample = %d, unsigned long multiSampleQuality = %d, int lockable = %d, IDirect3DSurface9 **surface = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, format, multiSample, multiSampleQuality, lockable, surface, sharedHandle);
+
+ return Direct3DDevice9::CreateRenderTarget(width, height, format, multiSample, multiSampleQuality, lockable, surface, sharedHandle);
+ }
+
+ long Direct3DDevice9Ex::CreateStateBlock(D3DSTATEBLOCKTYPE type, IDirect3DStateBlock9 **stateBlock)
+ {
+ TRACE("D3DSTATEBLOCKTYPE type = %d, IDirect3DStateBlock9 **stateBlock = 0x%0.8p", type, stateBlock);
+
+ return Direct3DDevice9::CreateStateBlock(type, stateBlock);
+ }
+
+ long Direct3DDevice9Ex::CreateTexture(unsigned int width, unsigned int height, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DTexture9 **texture, void **sharedHandle)
+ {
+ TRACE("unsigned int width = %d, unsigned int height = %d, unsigned int levels = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DTexture9 **texture = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, levels, usage, format, pool, texture, sharedHandle);
+
+ return Direct3DDevice9::CreateTexture(width, height, levels, usage, format, pool, texture, sharedHandle);
+ }
+
+ long Direct3DDevice9Ex::CreateVertexBuffer(unsigned int length, unsigned long usage, unsigned long FVF, D3DPOOL pool, IDirect3DVertexBuffer9 **vertexBuffer, void **sharedHandle)
+ {
+ TRACE("unsigned int length = %d, unsigned long usage = %d, unsigned long FVF = 0x%0.8X, D3DPOOL pool = %d, IDirect3DVertexBuffer9 **vertexBuffer = 0x%0.8p, void **sharedHandle = 0x%0.8p", length, usage, FVF, pool, vertexBuffer, sharedHandle);
+
+ return Direct3DDevice9::CreateVertexBuffer(length, usage, FVF, pool, vertexBuffer, sharedHandle);
+ }
+
+ long Direct3DDevice9Ex::CreateVertexDeclaration(const D3DVERTEXELEMENT9 *vertexElements, IDirect3DVertexDeclaration9 **declaration)
+ {
+ TRACE("const D3DVERTEXELEMENT9 *vertexElements = 0x%0.8p, IDirect3DVertexDeclaration9 **declaration = 0x%0.8p", vertexElements, declaration);
+
+ return Direct3DDevice9::CreateVertexDeclaration(vertexElements, declaration);
+ }
+
+ long Direct3DDevice9Ex::CreateVertexShader(const unsigned long *function, IDirect3DVertexShader9 **shader)
+ {
+ TRACE("const unsigned long *function = 0x%0.8p, IDirect3DVertexShader9 **shader = 0x%0.8p", function, shader);
+
+ return Direct3DDevice9::CreateVertexShader(function, shader);
+ }
+
+ long Direct3DDevice9Ex::CreateVolumeTexture(unsigned int width, unsigned int height, unsigned int depth, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DVolumeTexture9 **volumeTexture, void **sharedHandle)
+ {
+ TRACE("unsigned int width = %d, unsigned int height = %d, unsigned int depth = %d, unsigned int levels = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DVolumeTexture9 **volumeTexture = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, depth, levels, usage, format, pool, volumeTexture, sharedHandle);
+
+ return Direct3DDevice9::CreateVolumeTexture(width, height, depth, levels, usage, format, pool, volumeTexture, sharedHandle);
+ }
+
+ long Direct3DDevice9Ex::DeletePatch(unsigned int handle)
+ {
+ TRACE("unsigned int handle = %d", handle);
+
+ return Direct3DDevice9::DeletePatch(handle);
+ }
+
+ long Direct3DDevice9Ex::DrawIndexedPrimitive(D3DPRIMITIVETYPE type, int baseVertexIndex, unsigned int minIndex, unsigned int numVertices, unsigned int startIndex, unsigned int primitiveCount)
+ {
+ TRACE("D3DPRIMITIVETYPE type = %d, int baseVertexIndex = %d, unsigned int minIndex = %d, unsigned int numVertices = %d, unsigned int startIndex = %d, unsigned int primitiveCount = %d", type, baseVertexIndex, minIndex, numVertices, startIndex, primitiveCount);
+
+ return Direct3DDevice9::DrawIndexedPrimitive(type, baseVertexIndex, minIndex, numVertices, startIndex, primitiveCount);
+ }
+
+ long Direct3DDevice9Ex::DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE type, unsigned int minIndex, unsigned int numVertices, unsigned int primitiveCount, const void *indexData, D3DFORMAT indexDataFormat, const void *vertexStreamZeroData, unsigned int vertexStreamZeroStride)
+ {
+ TRACE("D3DPRIMITIVETYPE type = %d, unsigned int minIndex = %d, unsigned int numVertices = %d, unsigned int primitiveCount = %d, const void *indexData = 0x%0.8p, D3DFORMAT indexDataFormat = %d, const void *vertexStreamZeroData = 0x%0.8p, unsigned int vertexStreamZeroStride = %d", type, minIndex, numVertices, primitiveCount, indexData, indexDataFormat, vertexStreamZeroData, vertexStreamZeroStride);
+
+ return Direct3DDevice9::DrawIndexedPrimitiveUP(type, minIndex, numVertices, primitiveCount, indexData, indexDataFormat, vertexStreamZeroData, vertexStreamZeroStride);
+ }
+
+ long Direct3DDevice9Ex::DrawPrimitive(D3DPRIMITIVETYPE primitiveType, unsigned int startVertex, unsigned int primitiveCount)
+ {
+ TRACE("D3DPRIMITIVETYPE primitiveType = %d, unsigned int startVertex = %d, unsigned int primitiveCount = %d", primitiveType, startVertex, primitiveCount);
+
+ return Direct3DDevice9::DrawPrimitive(primitiveType, startVertex, primitiveCount);
+ }
+
+ long Direct3DDevice9Ex::DrawPrimitiveUP(D3DPRIMITIVETYPE primitiveType, unsigned int primitiveCount, const void *vertexStreamZeroData, unsigned int vertexStreamZeroStride)
+ {
+ TRACE("D3DPRIMITIVETYPE primitiveType = %d, unsigned int primitiveCount = %d, const void *vertexStreamZeroData = 0x%0.8p, unsigned int vertexStreamZeroStride = %d", primitiveType, primitiveCount, vertexStreamZeroData, vertexStreamZeroStride);
+
+ return Direct3DDevice9::DrawPrimitiveUP(primitiveType, primitiveCount, vertexStreamZeroData, vertexStreamZeroStride);
+ }
+
+ long Direct3DDevice9Ex::DrawRectPatch(unsigned int handle, const float *numSegs, const D3DRECTPATCH_INFO *rectPatchInfo)
+ {
+ TRACE("unsigned int handle = %d, const float *numSegs = 0x%0.8p, const D3DRECTPATCH_INFO *rectPatchInfo = 0x%0.8p", handle, numSegs, rectPatchInfo);
+
+ return Direct3DDevice9::DrawRectPatch(handle, numSegs, rectPatchInfo);
+ }
+
+ long Direct3DDevice9Ex::DrawTriPatch(unsigned int handle, const float *numSegs, const D3DTRIPATCH_INFO *triPatchInfo)
+ {
+ TRACE("unsigned int handle = %d, const float *numSegs = 0x%0.8p, const D3DTRIPATCH_INFO *triPatchInfo = 0x%0.8p", handle, numSegs, triPatchInfo);
+
+ return Direct3DDevice9::DrawTriPatch(handle, numSegs, triPatchInfo);
+ }
+
+ long Direct3DDevice9Ex::EndScene()
+ {
+ TRACE("void");
+
+ return Direct3DDevice9::EndScene();
+ }
+
+ long Direct3DDevice9Ex::EndStateBlock(IDirect3DStateBlock9 **stateBlock)
+ {
+ TRACE("IDirect3DStateBlock9 **stateBlock = 0x%0.8p", stateBlock);
+
+ return Direct3DDevice9::EndStateBlock(stateBlock);
+ }
+
+ long Direct3DDevice9Ex::EvictManagedResources()
+ {
+ TRACE("void");
+
+ return Direct3DDevice9::EvictManagedResources();
+ }
+
+ unsigned int Direct3DDevice9Ex::GetAvailableTextureMem()
+ {
+ TRACE("void");
+
+ return Direct3DDevice9::GetAvailableTextureMem();
+ }
+
+ long Direct3DDevice9Ex::GetBackBuffer(unsigned int swapChainIndex, unsigned int backBufferIndex, D3DBACKBUFFER_TYPE type, IDirect3DSurface9 **backBuffer)
+ {
+ TRACE("unsigned int swapChainIndex = %d, unsigned int backBufferIndex = %d, D3DBACKBUFFER_TYPE type = %d, IDirect3DSurface9 **backBuffer = 0x%0.8p", swapChainIndex, backBufferIndex, type, backBuffer);
+
+ return Direct3DDevice9::GetBackBuffer(swapChainIndex, backBufferIndex, type, backBuffer);
+ }
+
+ long Direct3DDevice9Ex::GetClipPlane(unsigned long index, float *plane)
+ {
+ TRACE("unsigned long index = %d, float *plane = 0x%0.8p", index, plane);
+
+ return Direct3DDevice9::GetClipPlane(index, plane);
+ }
+
+ long Direct3DDevice9Ex::GetClipStatus(D3DCLIPSTATUS9 *clipStatus)
+ {
+ TRACE("D3DCLIPSTATUS9 *clipStatus = 0x%0.8p", clipStatus);
+
+ return Direct3DDevice9::GetClipStatus(clipStatus);
+ }
+
+ long Direct3DDevice9Ex::GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS *parameters)
+ {
+ TRACE("D3DDEVICE_CREATION_PARAMETERS *parameters = 0x%0.8p", parameters);
+
+ return Direct3DDevice9::GetCreationParameters(parameters);
+ }
+
+ long Direct3DDevice9Ex::GetCurrentTexturePalette(unsigned int *paletteNumber)
+ {
+ TRACE("unsigned int *paletteNumber = 0x%0.8p", paletteNumber);
+
+ return Direct3DDevice9::GetCurrentTexturePalette(paletteNumber);
+ }
+
+ long Direct3DDevice9Ex::GetDepthStencilSurface(IDirect3DSurface9 **depthStencilSurface)
+ {
+ TRACE("IDirect3DSurface9 **depthStencilSurface = 0x%0.8p", depthStencilSurface);
+
+ return Direct3DDevice9::GetDepthStencilSurface(depthStencilSurface);
+ }
+
+ long Direct3DDevice9Ex::GetDeviceCaps(D3DCAPS9 *caps)
+ {
+ TRACE("D3DCAPS9 *caps = 0x%0.8p", caps);
+
+ return d3d9ex->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, caps);
+ }
+
+ long Direct3DDevice9Ex::GetDirect3D(IDirect3D9 **d3d9)
+ {
+ TRACE("IDirect3D9 **d3d9 = 0x%0.8p", d3d9);
+
+ return Direct3DDevice9::GetDirect3D(d3d9);
+ }
+
+ long Direct3DDevice9Ex::GetDisplayMode(unsigned int index, D3DDISPLAYMODE *mode)
+ {
+ TRACE("unsigned int index = %d, D3DDISPLAYMODE *mode = 0x%0.8p", index, mode);
+
+ return Direct3DDevice9::GetDisplayMode(index, mode);
+ }
+
+ long Direct3DDevice9Ex::GetFrontBufferData(unsigned int index, IDirect3DSurface9 *destSurface)
+ {
+ TRACE("unsigned int index = %d, IDirect3DSurface9 *destSurface = %p", index, destSurface);
+
+ return Direct3DDevice9::GetFrontBufferData(index, destSurface);
+ }
+
+ long Direct3DDevice9Ex::GetFVF(unsigned long *FVF)
+ {
+ TRACE("unsigned long *FVF = 0x%0.8p", FVF);
+
+ return Direct3DDevice9::GetFVF(FVF);
+ }
+
+ void Direct3DDevice9Ex::GetGammaRamp(unsigned int index, D3DGAMMARAMP *ramp)
+ {
+ TRACE("unsigned int index = %d, D3DGAMMARAMP *ramp = 0x%0.8p", index, ramp);
+
+ return Direct3DDevice9::GetGammaRamp(index, ramp);
+ }
+
+ long Direct3DDevice9Ex::GetIndices(IDirect3DIndexBuffer9 **indexData)
+ {
+ TRACE("IDirect3DIndexBuffer9 **indexData = 0x%0.8p", indexData);
+
+ return Direct3DDevice9::GetIndices(indexData);
+ }
+
+ long Direct3DDevice9Ex::GetLight(unsigned long index, D3DLIGHT9 *light)
+ {
+ TRACE("unsigned long index = %d, D3DLIGHT9 *light = 0x%0.8p", index, light);
+
+ return Direct3DDevice9::GetLight(index, light);
+ }
+
+ long Direct3DDevice9Ex::GetLightEnable(unsigned long index, int *enable)
+ {
+ TRACE("unsigned long index = %d, int *enable = 0x%0.8p", index, enable);
+
+ return Direct3DDevice9::GetLightEnable(index, enable);
+ }
+
+ long Direct3DDevice9Ex::GetMaterial(D3DMATERIAL9 *material)
+ {
+ TRACE("D3DMATERIAL9 *material = 0x%0.8p", material);
+
+ return Direct3DDevice9::GetMaterial(material);
+ }
+
+ float Direct3DDevice9Ex::GetNPatchMode()
+ {
+ TRACE("void");
+
+ return Direct3DDevice9::GetNPatchMode();
+ }
+
+ unsigned int Direct3DDevice9Ex::GetNumberOfSwapChains()
+ {
+ TRACE("void");
+
+ return Direct3DDevice9::GetNumberOfSwapChains();
+ }
+
+ long Direct3DDevice9Ex::GetPaletteEntries(unsigned int paletteNumber, PALETTEENTRY *entries)
+ {
+ TRACE("unsigned int paletteNumber = %d, PALETTEENTRY *entries = 0x%0.8p", paletteNumber, entries);
+
+ return Direct3DDevice9::GetPaletteEntries(paletteNumber, entries);
+ }
+
+ long Direct3DDevice9Ex::GetPixelShader(IDirect3DPixelShader9 **shader)
+ {
+ TRACE("IDirect3DPixelShader9 **shader = 0x%0.8p", shader);
+
+ return Direct3DDevice9::GetPixelShader(shader);
+ }
+
+ long Direct3DDevice9Ex::GetPixelShaderConstantB(unsigned int startRegister, int *constantData, unsigned int count)
+ {
+ TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ return Direct3DDevice9::GetPixelShaderConstantB(startRegister, constantData, count);
+ }
+
+ long Direct3DDevice9Ex::GetPixelShaderConstantF(unsigned int startRegister, float *constantData, unsigned int count)
+ {
+ TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ return Direct3DDevice9::GetPixelShaderConstantF(startRegister, constantData, count);
+ }
+
+ long Direct3DDevice9Ex::GetPixelShaderConstantI(unsigned int startRegister, int *constantData, unsigned int count)
+ {
+ TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ return Direct3DDevice9::GetPixelShaderConstantI(startRegister, constantData, count);
+ }
+
+ long Direct3DDevice9Ex::GetRasterStatus(unsigned int swapChain, D3DRASTER_STATUS *rasterStatus)
+ {
+ TRACE("unsigned int swapChain = %d, D3DRASTER_STATUS *rasterStatus = 0x%0.8p", swapChain, rasterStatus);
+
+ return Direct3DDevice9::GetRasterStatus(swapChain, rasterStatus);
+ }
+
+ long Direct3DDevice9Ex::GetRenderState(D3DRENDERSTATETYPE state, unsigned long *value)
+ {
+ TRACE("D3DRENDERSTATETYPE state = %d, unsigned long *value = 0x%0.8p", state, value);
+
+ return Direct3DDevice9::GetRenderState(state, value);
+ }
+
+ long Direct3DDevice9Ex::GetRenderTarget(unsigned long index, IDirect3DSurface9 **renderTarget)
+ {
+ TRACE("unsigned long index = %d, IDirect3DSurface9 **renderTarget = 0x%0.8p", index, renderTarget);
+
+ return Direct3DDevice9::GetRenderTarget(index, renderTarget);
+ }
+
+ long Direct3DDevice9Ex::GetRenderTargetData(IDirect3DSurface9 *renderTarget, IDirect3DSurface9 *destSurface)
+ {
+ TRACE("IDirect3DSurface9 *renderTarget = 0x%0.8p, IDirect3DSurface9 *destSurface = 0x%0.8p", renderTarget, destSurface);
+
+ return Direct3DDevice9::GetRenderTargetData(renderTarget, destSurface);
+ }
+
+ long Direct3DDevice9Ex::GetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE state, unsigned long *value)
+ {
+ TRACE("unsigned long sampler = %d, D3DSAMPLERSTATETYPE type = %d, unsigned long *value = 0x%0.8p", sampler, state, value);
+
+ return Direct3DDevice9::GetSamplerState(sampler, state, value);
+ }
+
+ long Direct3DDevice9Ex::GetScissorRect(RECT *rect)
+ {
+ TRACE("RECT *rect = 0x%0.8p", rect);
+
+ return Direct3DDevice9::GetScissorRect(rect);
+ }
+
+ int Direct3DDevice9Ex::GetSoftwareVertexProcessing()
+ {
+ TRACE("void");
+
+ return Direct3DDevice9::GetSoftwareVertexProcessing();
+ }
+
+ long Direct3DDevice9Ex::GetStreamSource(unsigned int streamNumber, IDirect3DVertexBuffer9 **streamData, unsigned int *offset, unsigned int *stride)
+ {
+ TRACE("unsigned int streamNumber = %d, IDirect3DVertexBuffer9 **streamData = 0x%0.8p, unsigned int *offset = 0x%0.8p, unsigned int *stride = 0x%0.8p", streamNumber, streamData, offset, stride);
+
+ return Direct3DDevice9::GetStreamSource(streamNumber, streamData, offset, stride);
+ }
+
+ long Direct3DDevice9Ex::GetStreamSourceFreq(unsigned int streamNumber, unsigned int *divider)
+ {
+ TRACE("unsigned int streamNumber = %d, unsigned int *divider = 0x%0.8p", streamNumber, divider);
+
+ return Direct3DDevice9::GetStreamSourceFreq(streamNumber, divider);
+ }
+
+ long Direct3DDevice9Ex::GetSwapChain(unsigned int index, IDirect3DSwapChain9 **swapChain)
+ {
+ TRACE("unsigned int index = %d, IDirect3DSwapChain9 **swapChain = 0x%0.8p", index, swapChain);
+
+ return Direct3DDevice9::GetSwapChain(index, swapChain);
+ }
+
+ long Direct3DDevice9Ex::GetTexture(unsigned long sampler, IDirect3DBaseTexture9 **texture)
+ {
+ TRACE("unsigned long sampler = %d, IDirect3DBaseTexture9 **texture = 0x%0.8p", sampler, texture);
+
+ return Direct3DDevice9::GetTexture(sampler, texture);
+ }
+
+ long Direct3DDevice9Ex::GetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long *value)
+ {
+ TRACE("unsigned long stage = %d, D3DTEXTURESTAGESTATETYPE type = %d, unsigned long *value = 0x%0.8p", stage, type, value);
+
+ return Direct3DDevice9::GetTextureStageState(stage, type, value);
+ }
+
+ long Direct3DDevice9Ex::GetTransform(D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix)
+ {
+ TRACE("D3DTRANSFORMSTATETYPE state = %d, D3DMATRIX *matrix = 0x%0.8p", state, matrix);
+
+ return Direct3DDevice9::GetTransform(state, matrix);
+ }
+
+ long Direct3DDevice9Ex::GetVertexDeclaration(IDirect3DVertexDeclaration9 **declaration)
+ {
+ TRACE("IDirect3DVertexDeclaration9 **declaration = 0x%0.8p", declaration);
+
+ return Direct3DDevice9::GetVertexDeclaration(declaration);
+ }
+
+ long Direct3DDevice9Ex::GetVertexShader(IDirect3DVertexShader9 **shader)
+ {
+ TRACE("IDirect3DVertexShader9 **shader = 0x%0.8p", shader);
+
+ return Direct3DDevice9::GetVertexShader(shader);
+ }
+
+ long Direct3DDevice9Ex::GetVertexShaderConstantB(unsigned int startRegister, int *constantData, unsigned int count)
+ {
+ TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ return Direct3DDevice9::GetVertexShaderConstantB(startRegister, constantData, count);
+ }
+
+ long Direct3DDevice9Ex::GetVertexShaderConstantF(unsigned int startRegister, float *constantData, unsigned int count)
+ {
+ TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ return Direct3DDevice9::GetVertexShaderConstantF(startRegister, constantData, count);
+ }
+
+ long Direct3DDevice9Ex::GetVertexShaderConstantI(unsigned int startRegister, int *constantData, unsigned int count)
+ {
+ TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ return Direct3DDevice9::GetVertexShaderConstantI(startRegister, constantData, count);
+ }
+
+ long Direct3DDevice9Ex::GetViewport(D3DVIEWPORT9 *viewport)
+ {
+ TRACE("D3DVIEWPORT9 *viewport = 0x%0.8p", viewport);
+
+ return Direct3DDevice9::GetViewport(viewport);
+ }
+
+ long Direct3DDevice9Ex::LightEnable(unsigned long index, int enable)
+ {
+ TRACE("unsigned long index = %d, int enable = %d", index, enable);
+
+ return Direct3DDevice9::LightEnable(index, enable);
+ }
+
+ long Direct3DDevice9Ex::MultiplyTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
+ {
+ TRACE("D3DTRANSFORMSTATETYPE state = %d, const D3DMATRIX *matrix = 0x%0.8p", state, matrix);
+
+ return Direct3DDevice9::MultiplyTransform(state, matrix);
+ }
+
+ long Direct3DDevice9Ex::Present(const RECT *sourceRect, const RECT *destRect, HWND destWindowOverride, const RGNDATA *dirtyRegion)
+ {
+ TRACE("const RECT *sourceRect = 0x%0.8p, const RECT *destRect = 0x%0.8p, HWND destWindowOverride = %d, const RGNDATA *dirtyRegion = 0x%0.8p", sourceRect, destRect, destWindowOverride, dirtyRegion);
+
+ return Direct3DDevice9::Present(sourceRect, destRect, destWindowOverride, dirtyRegion);
+ }
+
+ long Direct3DDevice9Ex::ProcessVertices(unsigned int srcStartIndex, unsigned int destIndex, unsigned int vertexCount, IDirect3DVertexBuffer9 *destBuffer, IDirect3DVertexDeclaration9 *vertexDeclaration, unsigned long flags)
+ {
+ TRACE("unsigned int srcStartIndex = %d, unsigned int destIndex = %d, unsigned int vertexCount = %d, IDirect3DVertexBuffer9 *destBuffer = 0x%0.8p, IDirect3DVertexDeclaration9 *vertexDeclaration = 0x%0.8p, unsigned long flags = %d", srcStartIndex, destIndex, vertexCount, destBuffer, vertexDeclaration, flags);
+
+ return Direct3DDevice9::ProcessVertices(srcStartIndex, destIndex, vertexCount, destBuffer, vertexDeclaration, flags);
+ }
+
+ long Direct3DDevice9Ex::Reset(D3DPRESENT_PARAMETERS *presentParameters)
+ {
+ TRACE("D3DPRESENT_PARAMETERS *presentParameters = 0x%0.8p", presentParameters);
+
+ return Direct3DDevice9::Reset(presentParameters);
+ }
+
+ long Direct3DDevice9Ex::SetClipPlane(unsigned long index, const float *plane)
+ {
+ TRACE("unsigned long index = %d, const float *plane = 0x%0.8p", index, plane);
+
+ return Direct3DDevice9::SetClipPlane(index, plane);
+ }
+
+ long Direct3DDevice9Ex::SetClipStatus(const D3DCLIPSTATUS9 *clipStatus)
+ {
+ TRACE("const D3DCLIPSTATUS9 *clipStatus = 0x%0.8p", clipStatus);
+
+ return Direct3DDevice9::SetClipStatus(clipStatus);
+ }
+
+ long Direct3DDevice9Ex::SetCurrentTexturePalette(unsigned int paletteNumber)
+ {
+ TRACE("unsigned int paletteNumber = %d", paletteNumber);
+
+ return Direct3DDevice9::SetCurrentTexturePalette(paletteNumber);
+ }
+
+ void Direct3DDevice9Ex::SetCursorPosition(int x, int y, unsigned long flags)
+ {
+ TRACE("int x = %d, int y = %d, unsigned long flags = 0x%0.8X", x, y, flags);
+
+ return Direct3DDevice9::SetCursorPosition(x, y, flags);
+ }
+
+ long Direct3DDevice9Ex::SetCursorProperties(unsigned int x, unsigned int y, IDirect3DSurface9 *cursorBitmap)
+ {
+ TRACE("unsigned int x = %d, unsigned int y = %d, IDirect3DSurface9 *cursorBitmap = 0x%0.8p", x, y, cursorBitmap);
+
+ return Direct3DDevice9::SetCursorProperties(x, y, cursorBitmap);
+ }
+
+ long Direct3DDevice9Ex::SetDepthStencilSurface(IDirect3DSurface9 *iDepthStencil)
+ {
+ TRACE("IDirect3DSurface9 *newDepthStencil = 0x%0.8p", iDepthStencil);
+
+ return Direct3DDevice9::SetDepthStencilSurface(iDepthStencil);
+ }
+
+ long Direct3DDevice9Ex::SetDialogBoxMode(int enableDialogs)
+ {
+ TRACE("int enableDialogs = %d", enableDialogs);
+
+ return Direct3DDevice9::SetDialogBoxMode(enableDialogs);
+ }
+
+ long Direct3DDevice9Ex::SetFVF(unsigned long FVF)
+ {
+ TRACE("unsigned long FVF = 0x%0.8X", FVF);
+
+ return Direct3DDevice9::SetFVF(FVF);
+ }
+
+ void Direct3DDevice9Ex::SetGammaRamp(unsigned int index, unsigned long flags, const D3DGAMMARAMP *ramp)
+ {
+ TRACE("unsigned int index = %d, unsigned long flags = 0x%0.8X, const D3DGAMMARAMP *ramp = 0x%0.8p", index, flags, ramp);
+
+ return Direct3DDevice9::SetGammaRamp(index, flags, ramp);
+ }
+
+ long Direct3DDevice9Ex::SetIndices(IDirect3DIndexBuffer9* iIndexBuffer)
+ {
+ TRACE("IDirect3DIndexBuffer9* indexData = 0x%0.8p", iIndexBuffer);
+
+ return Direct3DDevice9::SetIndices(iIndexBuffer);
+ }
+
+ long Direct3DDevice9Ex::SetLight(unsigned long index, const D3DLIGHT9 *light)
+ {
+ TRACE("unsigned long index = %d, const D3DLIGHT9 *light = 0x%0.8p", index, light);
+
+ return Direct3DDevice9::SetLight(index, light);
+ }
+
+ long Direct3DDevice9Ex::SetMaterial(const D3DMATERIAL9 *material)
+ {
+ TRACE("const D3DMATERIAL9 *material = 0x%0.8p", material);
+
+ return Direct3DDevice9::SetMaterial(material);
+ }
+
+ long Direct3DDevice9Ex::SetNPatchMode(float segments)
+ {
+ TRACE("float segments = %f", segments);
+
+ return Direct3DDevice9::SetNPatchMode(segments);
+ }
+
+ long Direct3DDevice9Ex::SetPaletteEntries(unsigned int paletteNumber, const PALETTEENTRY *entries)
+ {
+ TRACE("unsigned int paletteNumber = %d, const PALETTEENTRY *entries = 0x%0.8p", paletteNumber, entries);
+
+ return Direct3DDevice9::SetPaletteEntries(paletteNumber, entries);
+ }
+
+ long Direct3DDevice9Ex::SetPixelShader(IDirect3DPixelShader9 *iPixelShader)
+ {
+ TRACE("IDirect3DPixelShader9 *shader = 0x%0.8p", iPixelShader);
+
+ return Direct3DDevice9::SetPixelShader(iPixelShader);
+ }
+
+ long Direct3DDevice9Ex::SetPixelShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count)
+ {
+ TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ return Direct3DDevice9::SetPixelShaderConstantB(startRegister, constantData, count);
+ }
+
+ long Direct3DDevice9Ex::SetPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
+ {
+ TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ return Direct3DDevice9::SetPixelShaderConstantF(startRegister, constantData, count);
+ }
+
+ long Direct3DDevice9Ex::SetPixelShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count)
+ {
+ TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ return Direct3DDevice9::SetPixelShaderConstantI(startRegister, constantData, count);
+ }
+
+ long Direct3DDevice9Ex::SetRenderState(D3DRENDERSTATETYPE state, unsigned long value)
+ {
+ TRACE("D3DRENDERSTATETYPE state = %d, unsigned long value = %d", state, value);
+
+ return Direct3DDevice9::SetRenderState(state, value);
+ }
+
+ long Direct3DDevice9Ex::SetRenderTarget(unsigned long index, IDirect3DSurface9 *iRenderTarget)
+ {
+ TRACE("unsigned long index = %d, IDirect3DSurface9 *newRenderTarget = 0x%0.8p", index, iRenderTarget);
+
+ return Direct3DDevice9::SetRenderTarget(index, iRenderTarget);
+ }
+
+ long Direct3DDevice9Ex::SetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE state, unsigned long value)
+ {
+ TRACE("unsigned long sampler = %d, D3DSAMPLERSTATETYPE state = %d, unsigned long value = %d", sampler, state, value);
+
+ return Direct3DDevice9::SetSamplerState(sampler, state, value);
+ }
+
+ long Direct3DDevice9Ex::SetScissorRect(const RECT *rect)
+ {
+ TRACE("const RECT *rect = 0x%0.8p", rect);
+
+ return Direct3DDevice9::SetScissorRect(rect);
+ }
+
+ long Direct3DDevice9Ex::SetSoftwareVertexProcessing(int software)
+ {
+ TRACE("int software = %d", software);
+
+ return Direct3DDevice9::SetSoftwareVertexProcessing(software);
+ }
+
+ long Direct3DDevice9Ex::SetStreamSource(unsigned int stream, IDirect3DVertexBuffer9 *iVertexBuffer, unsigned int offset, unsigned int stride)
+ {
+ TRACE("unsigned int stream = %d, IDirect3DVertexBuffer9 *data = 0x%0.8p, unsigned int offset = %d, unsigned int stride = %d", stream, iVertexBuffer, offset, stride);
+
+ return Direct3DDevice9::SetStreamSource(stream, iVertexBuffer, offset, stride);
+ }
+
+ long Direct3DDevice9Ex::SetStreamSourceFreq(unsigned int streamNumber, unsigned int divider)
+ {
+ TRACE("unsigned int streamNumber = %d, unsigned int divider = %d", streamNumber, divider);
+
+ return Direct3DDevice9::SetStreamSourceFreq(streamNumber, divider);
+ }
+
+ long Direct3DDevice9Ex::SetTexture(unsigned long sampler, IDirect3DBaseTexture9 *iBaseTexture)
+ {
+ TRACE("unsigned long sampler = %d, IDirect3DBaseTexture9 *texture = 0x%0.8p", sampler, iBaseTexture);
+
+ return Direct3DDevice9::SetTexture(sampler, iBaseTexture);
+ }
+
+ long Direct3DDevice9Ex::SetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long value)
+ {
+ TRACE("unsigned long stage = %d, D3DTEXTURESTAGESTATETYPE type = %d, unsigned long value = %d", stage, type, value);
+
+ return Direct3DDevice9::SetTextureStageState(stage, type, value);
+ }
+
+ long Direct3DDevice9Ex::SetTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
+ {
+ TRACE("D3DTRANSFORMSTATETYPE state = %d, const D3DMATRIX *matrix = 0x%0.8p", state, matrix);
+
+ return Direct3DDevice9::SetTransform(state, matrix);
+ }
+
+ long Direct3DDevice9Ex::SetVertexDeclaration(IDirect3DVertexDeclaration9 *iVertexDeclaration)
+ {
+ TRACE("IDirect3DVertexDeclaration9 *declaration = 0x%0.8p", iVertexDeclaration);
+
+ return Direct3DDevice9::SetVertexDeclaration(iVertexDeclaration);
+ }
+
+ long Direct3DDevice9Ex::SetVertexShader(IDirect3DVertexShader9 *iVertexShader)
+ {
+ TRACE("IDirect3DVertexShader9 *shader = 0x%0.8p", iVertexShader);
+
+ return Direct3DDevice9::SetVertexShader(iVertexShader);
+ }
+
+ long Direct3DDevice9Ex::SetVertexShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count)
+ {
+ TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ return Direct3DDevice9::SetVertexShaderConstantB(startRegister, constantData, count);
+ }
+
+ long Direct3DDevice9Ex::SetVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
+ {
+ TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ return Direct3DDevice9::SetVertexShaderConstantF(startRegister, constantData, count);
+ }
+
+ long Direct3DDevice9Ex::SetVertexShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count)
+ {
+ TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+ return Direct3DDevice9::SetVertexShaderConstantI(startRegister, constantData, count);
+ }
+
+ long Direct3DDevice9Ex::SetViewport(const D3DVIEWPORT9 *viewport)
+ {
+ TRACE("const D3DVIEWPORT9 *viewport = 0x%0.8p", viewport);
+
+ return Direct3DDevice9::SetViewport(viewport);
+ }
+
+ int Direct3DDevice9Ex::ShowCursor(int show)
+ {
+ TRACE("int show = %d", show);
+
+ return Direct3DDevice9::ShowCursor(show);
+ }
+
+ long Direct3DDevice9Ex::StretchRect(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destSurface, const RECT *destRect, D3DTEXTUREFILTERTYPE filter)
+ {
+ TRACE("IDirect3DSurface9 *sourceSurface = 0x%0.8p, const RECT *sourceRect = 0x%0.8p, IDirect3DSurface9 *destSurface = 0x%0.8p, const RECT *destRect = 0x%0.8p, D3DTEXTUREFILTERTYPE filter = %d", sourceSurface, sourceRect, destSurface, destRect, filter);
+
+ return Direct3DDevice9::StretchRect(sourceSurface, sourceRect, destSurface, destRect, filter);
+ }
+
+ long Direct3DDevice9Ex::TestCooperativeLevel()
+ {
+ TRACE("void");
+
+ return Direct3DDevice9::TestCooperativeLevel();
+ }
+
+ long Direct3DDevice9Ex::UpdateSurface(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destinationSurface, const POINT *destPoint)
+ {
+ TRACE("IDirect3DSurface9 *sourceSurface = 0x%0.8p, const RECT *sourceRect = 0x%0.8p, IDirect3DSurface9 *destinationSurface = 0x%0.8p, const POINT *destPoint = 0x%0.8p", sourceSurface, sourceRect, destinationSurface, destPoint);
+
+ return Direct3DDevice9::UpdateSurface(sourceSurface, sourceRect, destinationSurface, destPoint);
+ }
+
+ long Direct3DDevice9Ex::UpdateTexture(IDirect3DBaseTexture9 *sourceTexture, IDirect3DBaseTexture9 *destinationTexture)
+ {
+ TRACE("IDirect3DBaseTexture9 *sourceTexture = 0x%0.8p, IDirect3DBaseTexture9 *destinationTexture = 0x%0.8p", sourceTexture, destinationTexture);
+
+ return Direct3DDevice9::UpdateTexture(sourceTexture, destinationTexture);
+ }
+
+ long Direct3DDevice9Ex::ValidateDevice(unsigned long *numPasses)
+ {
+ TRACE("unsigned long *numPasses = 0x%0.8p", numPasses);
+
+ return Direct3DDevice9::ValidateDevice(numPasses);
+ }
+
+ HRESULT Direct3DDevice9Ex::SetConvolutionMonoKernel(UINT,UINT,float *,float *)
+ {
+ CriticalSection cs(this);
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ HRESULT Direct3DDevice9Ex::ComposeRects(IDirect3DSurface9 *,IDirect3DSurface9 *,IDirect3DVertexBuffer9 *,UINT,IDirect3DVertexBuffer9 *,D3DCOMPOSERECTSOP,int,int)
+ {
+ CriticalSection cs(this);
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ HRESULT Direct3DDevice9Ex::PresentEx(const RECT *,const RECT *,HWND,const RGNDATA *,DWORD)
+ {
+ CriticalSection cs(this);
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ HRESULT Direct3DDevice9Ex::GetGPUThreadPriority(INT *)
+ {
+ CriticalSection cs(this);
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ HRESULT Direct3DDevice9Ex::SetGPUThreadPriority(INT)
+ {
+ CriticalSection cs(this);
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ HRESULT Direct3DDevice9Ex::WaitForVBlank(UINT)
+ {
+ CriticalSection cs(this);
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ HRESULT Direct3DDevice9Ex::CheckResourceResidency(IDirect3DResource9 **,UINT32)
+ {
+ CriticalSection cs(this);
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ HRESULT Direct3DDevice9Ex::SetMaximumFrameLatency(UINT)
+ {
+ CriticalSection cs(this);
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ HRESULT Direct3DDevice9Ex::GetMaximumFrameLatency(UINT *)
+ {
+ CriticalSection cs(this);
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ HRESULT Direct3DDevice9Ex::CheckDeviceState(HWND destinationWindow)
+ {
+ CriticalSection cs(this);
+
+ // UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ HRESULT Direct3DDevice9Ex::CreateRenderTargetEx(UINT,UINT,D3DFORMAT,D3DMULTISAMPLE_TYPE,DWORD,BOOL,IDirect3DSurface9 **,HANDLE *,DWORD)
+ {
+ CriticalSection cs(this);
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ HRESULT Direct3DDevice9Ex::CreateOffscreenPlainSurfaceEx(UINT,UINT,D3DFORMAT,D3DPOOL,IDirect3DSurface9 **,HANDLE *,DWORD)
+ {
+ CriticalSection cs(this);
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ HRESULT Direct3DDevice9Ex::CreateDepthStencilSurfaceEx(UINT,UINT,D3DFORMAT,D3DMULTISAMPLE_TYPE,DWORD,BOOL,IDirect3DSurface9 **,HANDLE *,DWORD)
+ {
+ CriticalSection cs(this);
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ HRESULT Direct3DDevice9Ex::ResetEx(D3DPRESENT_PARAMETERS *,D3DDISPLAYMODEEX *)
+ {
+ CriticalSection cs(this);
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ HRESULT Direct3DDevice9Ex::GetDisplayModeEx(UINT,D3DDISPLAYMODEEX *,D3DDISPLAYROTATION *)
+ {
+ CriticalSection cs(this);
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+}
diff --git a/src/D3D9/Direct3DDevice9Ex.hpp b/src/D3D9/Direct3DDevice9Ex.hpp
new file mode 100644
index 0000000..e83d432
--- /dev/null
+++ b/src/D3D9/Direct3DDevice9Ex.hpp
@@ -0,0 +1,196 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Direct3DDevice9Ex_hpp
+#define D3D9_Direct3DDevice9Ex_hpp
+
+#include "Direct3DDevice9.hpp"
+
+#include "Direct3D9Ex.hpp"
+#include "Direct3DSwapChain9.hpp"
+
+#include "Stream.hpp"
+
+#include <d3d9.h>
+#include <map>
+#include <list>
+#include <vector>
+
+namespace sw
+{
+ class Renderer;
+ class Context;
+}
+
+namespace D3D9
+{
+ class Direct3DVertexDeclaration9;
+ class Direct3DStateBlock9;
+ class Direct3DSurface9;
+ class Direct3DPixelShader9;
+ class Direct3DVertexShader9;
+ class irect3DVertexDeclaration9;
+ class Direct3DVertexBuffer9;
+ class Direct3DIndexBuffer9;
+
+ class Direct3DDevice9Ex : public IDirect3DDevice9Ex, public Direct3DDevice9
+ {
+ public:
+ Direct3DDevice9Ex(const HINSTANCE instance, Direct3D9Ex *d3d9ex, unsigned int adapter, D3DDEVTYPE deviceType, HWND focusWindow, unsigned long behaviourFlags, D3DPRESENT_PARAMETERS *presentParameters);
+
+ virtual ~Direct3DDevice9Ex();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // IDirect3DDevice9 methods
+ long __stdcall TestCooperativeLevel();
+ unsigned int __stdcall GetAvailableTextureMem();
+ long __stdcall EvictManagedResources();
+ long __stdcall GetDirect3D(IDirect3D9 **D3D);
+ long __stdcall GetDeviceCaps(D3DCAPS9 *caps);
+ long __stdcall GetDisplayMode(unsigned int swapChain ,D3DDISPLAYMODE *mode);
+ long __stdcall GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS *parameters);
+ long __stdcall SetCursorProperties(unsigned int x, unsigned int y, IDirect3DSurface9 *cursorBitmap);
+ void __stdcall SetCursorPosition(int x, int y, unsigned long flags);
+ int __stdcall ShowCursor(int show);
+ long __stdcall CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS *presentParameters, IDirect3DSwapChain9 **swapChain);
+ long __stdcall GetSwapChain(unsigned int index, IDirect3DSwapChain9 **swapChain);
+ unsigned int __stdcall GetNumberOfSwapChains();
+ long __stdcall Reset(D3DPRESENT_PARAMETERS *presentParameters);
+ long __stdcall Present(const RECT *sourceRect, const RECT *destRect, HWND destWindowOverride, const RGNDATA *dirtyRegion);
+ long __stdcall GetBackBuffer(unsigned int swapChain, unsigned int index, D3DBACKBUFFER_TYPE type, IDirect3DSurface9 **backBuffer);
+ long __stdcall GetRasterStatus(unsigned int swapChain, D3DRASTER_STATUS *rasterStatus);
+ long __stdcall SetDialogBoxMode(int enableDialogs);
+ void __stdcall SetGammaRamp(unsigned int swapChain, unsigned long flags, const D3DGAMMARAMP *ramp);
+ void __stdcall GetGammaRamp(unsigned int swapChain, D3DGAMMARAMP *ramp);
+ long __stdcall CreateTexture(unsigned int width, unsigned int height, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DTexture9 **texture, void **sharedHandle);
+ long __stdcall CreateVolumeTexture(unsigned int width, unsigned int height, unsigned int depth, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DVolumeTexture9 **volumeTexture, void **sharedHandle);
+ long __stdcall CreateCubeTexture(unsigned int edgeLength, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DCubeTexture9 **cubeTexture, void **sharedHandle);
+ long __stdcall CreateVertexBuffer(unsigned int length, unsigned long usage, unsigned long FVF, D3DPOOL, IDirect3DVertexBuffer9 **vertexBuffer, void **sharedHandle);
+ long __stdcall CreateIndexBuffer(unsigned int length, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer9 **indexBuffer, void **sharedHandle);
+ long __stdcall CreateRenderTarget(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, unsigned long multiSampleQuality, int lockable, IDirect3DSurface9 **surface, void **sharedHandle);
+ long __stdcall CreateDepthStencilSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, unsigned long multiSampleQuality, int discard, IDirect3DSurface9 **surface, void **sharedHandle);
+ long __stdcall UpdateSurface(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destinationSurface, const POINT *destPoint);
+ long __stdcall UpdateTexture(IDirect3DBaseTexture9 *sourceTexture, IDirect3DBaseTexture9 *destinationTexture);
+ long __stdcall GetRenderTargetData(IDirect3DSurface9 *renderTarget, IDirect3DSurface9 *destSurface);
+ long __stdcall GetFrontBufferData(unsigned int swapChain, IDirect3DSurface9 *destSurface);
+ long __stdcall StretchRect(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destSurface, const RECT *destRect, D3DTEXTUREFILTERTYPE filter);
+ long __stdcall ColorFill(IDirect3DSurface9 *surface, const RECT *rect, D3DCOLOR color);
+ long __stdcall CreateOffscreenPlainSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DPOOL pool, IDirect3DSurface9 **surface, void **sharedHandle);
+ long __stdcall SetRenderTarget(unsigned long index, IDirect3DSurface9 *renderTarget);
+ long __stdcall GetRenderTarget(unsigned long index, IDirect3DSurface9 **renderTarget);
+ long __stdcall SetDepthStencilSurface(IDirect3DSurface9 *newDepthStencil);
+ long __stdcall GetDepthStencilSurface(IDirect3DSurface9 **depthStencilSurface);
+ long __stdcall BeginScene();
+ long __stdcall EndScene();
+ long __stdcall Clear(unsigned long Count, const D3DRECT *rects, unsigned long Flags, unsigned long Color, float Z, unsigned long Stencil);
+ long __stdcall SetTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix);
+ long __stdcall GetTransform(D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix);
+ long __stdcall MultiplyTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix);
+ long __stdcall SetViewport(const D3DVIEWPORT9 *viewport);
+ long __stdcall GetViewport(D3DVIEWPORT9 *viewport);
+ long __stdcall SetMaterial(const D3DMATERIAL9 *material);
+ long __stdcall GetMaterial(D3DMATERIAL9 *material);
+ long __stdcall SetLight(unsigned long index, const D3DLIGHT9 *light);
+ long __stdcall GetLight(unsigned long index, D3DLIGHT9 *light);
+ long __stdcall LightEnable(unsigned long index, int enable);
+ long __stdcall GetLightEnable(unsigned long index , int *enable);
+ long __stdcall SetClipPlane(unsigned long index, const float *plane);
+ long __stdcall GetClipPlane(unsigned long index, float *plane);
+ long __stdcall SetRenderState(D3DRENDERSTATETYPE state, unsigned long value);
+ long __stdcall GetRenderState(D3DRENDERSTATETYPE State, unsigned long *value);
+ long __stdcall CreateStateBlock(D3DSTATEBLOCKTYPE type, IDirect3DStateBlock9 **stateBlock);
+ long __stdcall BeginStateBlock();
+ long __stdcall EndStateBlock(IDirect3DStateBlock9 **stateBlock);
+ long __stdcall SetClipStatus(const D3DCLIPSTATUS9 *clipStatus);
+ long __stdcall GetClipStatus(D3DCLIPSTATUS9 *clipStatus);
+ long __stdcall GetTexture(unsigned long sampler, IDirect3DBaseTexture9 **texture);
+ long __stdcall SetTexture(unsigned long sampler, IDirect3DBaseTexture9 *texture);
+ long __stdcall GetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long *value);
+ long __stdcall SetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long value);
+ long __stdcall GetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE state, unsigned long *value);
+ long __stdcall SetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE state, unsigned long value);
+ long __stdcall ValidateDevice(unsigned long *numPasses);
+ long __stdcall SetPaletteEntries(unsigned int paletteNumber, const PALETTEENTRY *entries);
+ long __stdcall GetPaletteEntries(unsigned int paletteNumber, PALETTEENTRY *entries);
+ long __stdcall SetCurrentTexturePalette(unsigned int paletteNumber);
+ long __stdcall GetCurrentTexturePalette(unsigned int *paletteNumber);
+ long __stdcall SetScissorRect(const RECT *rect);
+ long __stdcall GetScissorRect(RECT *rect);
+ long __stdcall SetSoftwareVertexProcessing(int software);
+ int __stdcall GetSoftwareVertexProcessing();
+ long __stdcall SetNPatchMode(float segments);
+ float __stdcall GetNPatchMode();
+ long __stdcall DrawPrimitive(D3DPRIMITIVETYPE primitiveType, unsigned int startVertex, unsigned int primiveCount);
+ long __stdcall DrawIndexedPrimitive(D3DPRIMITIVETYPE type, int baseVertexIndex, unsigned int minIndex, unsigned int numVertices, unsigned int startIndex, unsigned int primitiveCount);
+ long __stdcall DrawPrimitiveUP(D3DPRIMITIVETYPE primitiveType, unsigned int primitiveCount, const void *vertexStreamZeroData, unsigned int vertexStreamZeroStride);
+ long __stdcall DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE type, unsigned int minVertexIndex, unsigned int numVertexIndices, unsigned int PrimitiveCount, const void *indexData, D3DFORMAT indexDataFormat, const void *vertexStreamZeroData, unsigned int VertexStreamZeroStride);
+ long __stdcall ProcessVertices(unsigned int srcStartIndex, unsigned int destIndex, unsigned int vertexCount, IDirect3DVertexBuffer9 *destBuffer, IDirect3DVertexDeclaration9 *vertexDeclaration, unsigned long flags);
+ long __stdcall CreateVertexDeclaration(const D3DVERTEXELEMENT9 *vertexElements, IDirect3DVertexDeclaration9 **declaration);
+ long __stdcall SetVertexDeclaration(IDirect3DVertexDeclaration9 *declaration);
+ long __stdcall GetVertexDeclaration(IDirect3DVertexDeclaration9 **declaration);
+ long __stdcall SetFVF(unsigned long FVF);
+ long __stdcall GetFVF(unsigned long *FVF);
+ long __stdcall CreateVertexShader(const unsigned long *function, IDirect3DVertexShader9 **shader);
+ long __stdcall SetVertexShader(IDirect3DVertexShader9 *shader);
+ long __stdcall GetVertexShader(IDirect3DVertexShader9 **shader);
+ long __stdcall SetVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
+ long __stdcall GetVertexShaderConstantF(unsigned int startRegister, float *constantData, unsigned int count);
+ long __stdcall SetVertexShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count);
+ long __stdcall GetVertexShaderConstantI(unsigned int startRegister, int *constantData, unsigned int count);
+ long __stdcall SetVertexShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count);
+ long __stdcall GetVertexShaderConstantB(unsigned int startRegister, int *constantData, unsigned int count);
+ long __stdcall SetStreamSource(unsigned int stream, IDirect3DVertexBuffer9 *data, unsigned int offset, unsigned int stride);
+ long __stdcall GetStreamSource(unsigned int streamNumber, IDirect3DVertexBuffer9 **streamData, unsigned int *offset, unsigned int *stride);
+ long __stdcall SetStreamSourceFreq(unsigned int streamNumber, unsigned int divider);
+ long __stdcall GetStreamSourceFreq(unsigned int streamNumber, unsigned int *divider);
+ long __stdcall SetIndices(IDirect3DIndexBuffer9 *indexData);
+ long __stdcall GetIndices(IDirect3DIndexBuffer9 **indexData);
+ long __stdcall CreatePixelShader(const unsigned long *function, IDirect3DPixelShader9 **shader);
+ long __stdcall SetPixelShader(IDirect3DPixelShader9 *shader);
+ long __stdcall GetPixelShader(IDirect3DPixelShader9 **shader);
+ long __stdcall SetPixelShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count);
+ long __stdcall GetPixelShaderConstantI(unsigned int startRegister, int *constantData, unsigned int count);
+ long __stdcall SetPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
+ long __stdcall GetPixelShaderConstantF(unsigned int startRegister, float *constantData, unsigned int count);
+ long __stdcall SetPixelShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count);
+ long __stdcall GetPixelShaderConstantB(unsigned int startRegister, int *constantData, unsigned int count);
+ long __stdcall DrawRectPatch(unsigned int handle, const float *numSegs, const D3DRECTPATCH_INFO *rectPatchInfo);
+ long __stdcall DrawTriPatch(unsigned int handle, const float *numSegs, const D3DTRIPATCH_INFO *triPatchInfo);
+ long __stdcall DeletePatch(unsigned int handle);
+ long __stdcall CreateQuery(D3DQUERYTYPE type, IDirect3DQuery9 **query);
+
+ // IDirect3DDevice9Ex methods
+ long __stdcall SetConvolutionMonoKernel(UINT,UINT,float *,float *);
+ long __stdcall ComposeRects(IDirect3DSurface9 *,IDirect3DSurface9 *,IDirect3DVertexBuffer9 *,UINT,IDirect3DVertexBuffer9 *,D3DCOMPOSERECTSOP,int,int);
+ long __stdcall PresentEx(const RECT *,const RECT *,HWND,const RGNDATA *,DWORD);
+ long __stdcall GetGPUThreadPriority(int *priority);
+ long __stdcall SetGPUThreadPriority(int priority);
+ long __stdcall WaitForVBlank(unsigned int swapChain);
+ long __stdcall CheckResourceResidency(IDirect3DResource9 **resourceArray, unsigned int numResources);
+ long __stdcall SetMaximumFrameLatency(unsigned int maxLatency);
+ long __stdcall GetMaximumFrameLatency(unsigned int *maxLatency);
+ long __stdcall CheckDeviceState(HWND destinationWindow);
+ long __stdcall CreateRenderTargetEx(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSampleType, unsigned long multiSampleQuality, int lockable, IDirect3DSurface9 **surface, void **sharedHandle, unsigned long usage);
+ long __stdcall CreateOffscreenPlainSurfaceEx(unsigned int width, unsigned int height, D3DFORMAT format, D3DPOOL pool, IDirect3DSurface9 **surface, void **sharedHandle, unsigned long usage);
+ long __stdcall CreateDepthStencilSurfaceEx(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSampleType, unsigned long multiSampleQuality, int discard, IDirect3DSurface9 **surface, void **sharedHandle, unsigned long usage);
+ long __stdcall ResetEx(D3DPRESENT_PARAMETERS *presentParameters, D3DDISPLAYMODEEX *fullscreenDisplayMode);
+ long __stdcall GetDisplayModeEx(unsigned int swapChain, D3DDISPLAYMODEEX *mode, D3DDISPLAYROTATION *rotation);
+
+ private:
+ Direct3D9Ex *const d3d9ex;
+ };
+}
+
+#endif // D3D9_Direct3DDevice9Ex_hpp
diff --git a/src/D3D9/Direct3DIndexBuffer9.cpp b/src/D3D9/Direct3DIndexBuffer9.cpp
new file mode 100644
index 0000000..eea9541
--- /dev/null
+++ b/src/D3D9/Direct3DIndexBuffer9.cpp
@@ -0,0 +1,234 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3DIndexBuffer9.hpp"
+
+#include "Direct3DDevice9.hpp"
+#include "Resource.hpp"
+#include "Debug.hpp"
+
+#include <assert.h>
+
+namespace D3D9
+{
+ Direct3DIndexBuffer9::Direct3DIndexBuffer9(Direct3DDevice9 *device, unsigned int length, unsigned long usage, D3DFORMAT format, D3DPOOL pool) : Direct3DResource9(device, D3DRTYPE_INDEXBUFFER, pool, length), length(length), usage(usage), format(format)
+ {
+ indexBuffer = new sw::Resource(length + 16);
+ lockCount = 0;
+ }
+
+ Direct3DIndexBuffer9::~Direct3DIndexBuffer9()
+ {
+ indexBuffer->destruct();
+ }
+
+ long Direct3DIndexBuffer9::QueryInterface(const IID &iid, void **object)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(iid == IID_IDirect3DIndexBuffer9 ||
+ iid == IID_IDirect3DResource9 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long Direct3DIndexBuffer9::AddRef()
+ {
+ TRACE("");
+
+ return Direct3DResource9::AddRef();
+ }
+
+ unsigned long Direct3DIndexBuffer9::Release()
+ {
+ TRACE("");
+
+ return Direct3DResource9::Release();
+ }
+
+ long Direct3DIndexBuffer9::FreePrivateData(const GUID &guid)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::FreePrivateData(guid);
+ }
+
+ long Direct3DIndexBuffer9::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::GetPrivateData(guid, data, size);
+ }
+
+ void Direct3DIndexBuffer9::PreLoad()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ Direct3DResource9::PreLoad();
+ }
+
+ long Direct3DIndexBuffer9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::SetPrivateData(guid, data, size, flags);
+ }
+
+ long Direct3DIndexBuffer9::GetDevice(IDirect3DDevice9 **device)
+ {
+ CriticalSection cs(this->device);
+
+ TRACE("");
+
+ return Direct3DResource9::GetDevice(device);
+ }
+
+ unsigned long Direct3DIndexBuffer9::SetPriority(unsigned long newPriority)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::SetPriority(newPriority);
+ }
+
+ unsigned long Direct3DIndexBuffer9::GetPriority()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::GetPriority();
+ }
+
+ D3DRESOURCETYPE Direct3DIndexBuffer9::GetType()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::GetType();
+ }
+
+ long Direct3DIndexBuffer9::GetDesc(D3DINDEXBUFFER_DESC *description)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!description)
+ {
+ return INVALIDCALL();
+ }
+
+ description->Format = format;
+ description->Pool = pool;
+ description->Size = length;
+ description->Type = GetType();
+ description->Usage = usage;
+
+ return 0;
+ }
+
+ long Direct3DIndexBuffer9::Lock(unsigned int offset, unsigned int size, void **data, unsigned long flags)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(offset == 0 && size == 0) // Lock whole buffer
+ {
+ size = length;
+ }
+
+ if(!data || offset > length || offset + size > length)
+ {
+ return INVALIDCALL();
+ }
+
+ void *buffer;
+
+ if(flags & D3DLOCK_DISCARD/* && usage & D3DUSAGE_DYNAMIC*/)
+ {
+ indexBuffer->destruct();
+ indexBuffer = new sw::Resource(length + 16);
+
+ buffer = (void*)indexBuffer->getBuffer();
+ }
+ else if(flags & D3DLOCK_NOOVERWRITE/* && usage & D3DUSAGE_DYNAMIC*/)
+ {
+ buffer = (void*)indexBuffer->getBuffer();
+ }
+ else
+ {
+ buffer = indexBuffer->lock(sw::PUBLIC);
+ lockCount++;
+ }
+
+ *data = (unsigned char*)buffer + offset;
+
+ return D3D_OK;
+ }
+
+ long Direct3DIndexBuffer9::Unlock()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(lockCount > 0)
+ {
+ indexBuffer->unlock();
+ lockCount--;
+ }
+
+ return D3D_OK;
+ }
+
+ sw::Resource *Direct3DIndexBuffer9::getResource() const
+ {
+ return indexBuffer;
+ }
+
+ bool Direct3DIndexBuffer9::is32Bit() const
+ {
+ switch(format)
+ {
+ case D3DFMT_INDEX16:
+ return false;
+ case D3DFMT_INDEX32:
+ return true;
+ default:
+ ASSERT(false);
+ }
+
+ return false;
+ }
+}
diff --git a/src/D3D9/Direct3DIndexBuffer9.hpp b/src/D3D9/Direct3DIndexBuffer9.hpp
new file mode 100644
index 0000000..39108a3
--- /dev/null
+++ b/src/D3D9/Direct3DIndexBuffer9.hpp
@@ -0,0 +1,68 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Direct3DIndexBuffer9_hpp
+#define D3D9_Direct3DIndexBuffer9_hpp
+
+#include "Direct3DResource9.hpp"
+
+#include <d3d9.h>
+
+namespace sw
+{
+ class Resource;
+}
+
+namespace D3D9
+{
+ class Direct3DIndexBuffer9 : public IDirect3DIndexBuffer9, public Direct3DResource9
+ {
+ public:
+ Direct3DIndexBuffer9(Direct3DDevice9 *device, unsigned int length, unsigned long usage, D3DFORMAT format, D3DPOOL pool);
+
+ virtual ~Direct3DIndexBuffer9();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // IDirect3DResource9 methods
+ long __stdcall FreePrivateData(const GUID &guid);
+ long __stdcall GetPrivateData(const GUID &guid, void *data, unsigned long *size);
+ void __stdcall PreLoad();
+ long __stdcall SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags);
+ long __stdcall GetDevice(IDirect3DDevice9 **device);
+ unsigned long __stdcall SetPriority(unsigned long newPriority);
+ unsigned long __stdcall GetPriority();
+ D3DRESOURCETYPE __stdcall GetType();
+
+ // IDirect3DIndexBuffer9 methods
+ long __stdcall GetDesc(D3DINDEXBUFFER_DESC *description);
+ long __stdcall Lock(unsigned int offset, unsigned int size, void **data, unsigned long flags);
+ long __stdcall Unlock();
+
+ // Internal methods
+ sw::Resource *getResource() const;
+ bool is32Bit() const;
+
+ private:
+ // Creation parameters
+ const unsigned int length;
+ const long usage;
+ const D3DFORMAT format;
+
+ sw::Resource *indexBuffer;
+ int lockCount;
+ };
+}
+
+#endif // D3D9_Direct3DIndexBuffer9_hpp
diff --git a/src/D3D9/Direct3DPixelShader9.cpp b/src/D3D9/Direct3DPixelShader9.cpp
new file mode 100644
index 0000000..aa1b9c9
--- /dev/null
+++ b/src/D3D9/Direct3DPixelShader9.cpp
@@ -0,0 +1,98 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3DPixelShader9.hpp"
+
+#include "Direct3DDevice9.hpp"
+#include "Debug.hpp"
+
+namespace D3D9
+{
+ Direct3DPixelShader9::Direct3DPixelShader9(Direct3DDevice9 *device, const unsigned long *shaderToken) : device(device), pixelShader(shaderToken)
+ {
+ }
+
+ Direct3DPixelShader9::~Direct3DPixelShader9()
+ {
+ }
+
+ long Direct3DPixelShader9::QueryInterface(const IID &iid, void **object)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(iid == IID_IDirect3DPixelShader9 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long Direct3DPixelShader9::AddRef()
+ {
+ TRACE("");
+
+ return Unknown::AddRef();
+ }
+
+ unsigned long Direct3DPixelShader9::Release()
+ {
+ TRACE("");
+
+ return Unknown::Release();
+ }
+
+ long Direct3DPixelShader9::GetDevice(IDirect3DDevice9 **device)
+ {
+ CriticalSection cs(this->device);
+
+ TRACE("");
+
+ if(!device)
+ {
+ return INVALIDCALL();
+ }
+
+ this->device->AddRef();
+ *device = this->device;
+
+ return D3D_OK;
+ }
+
+ long Direct3DPixelShader9::GetFunction(void *data, unsigned int *size)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!size)
+ {
+ return INVALIDCALL();
+ }
+
+ pixelShader.getFunction(data, size);
+
+ return D3D_OK;
+ }
+
+ const sw::PixelShader *Direct3DPixelShader9::getPixelShader() const
+ {
+ return &pixelShader;
+ }
+}
diff --git a/src/D3D9/Direct3DPixelShader9.hpp b/src/D3D9/Direct3DPixelShader9.hpp
new file mode 100644
index 0000000..a3f511e
--- /dev/null
+++ b/src/D3D9/Direct3DPixelShader9.hpp
@@ -0,0 +1,52 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Direct3DPixelShader9_hpp
+#define D3D9_Direct3DPixelShader9_hpp
+
+#include "Unknown.hpp"
+
+#include "PixelShader.hpp"
+
+#include <d3d9.h>
+
+namespace D3D9
+{
+ class Direct3DDevice9;
+
+ class Direct3DPixelShader9 : public IDirect3DPixelShader9, public Unknown
+ {
+ public:
+ Direct3DPixelShader9(Direct3DDevice9 *device, const unsigned long *shaderToken);
+
+ virtual ~Direct3DPixelShader9();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // IDirect3DPixelShader9 methods
+ long __stdcall GetDevice(IDirect3DDevice9 **device);
+ long __stdcall GetFunction(void *data, unsigned int *size);
+
+ // Internal methods
+ const sw::PixelShader *getPixelShader() const;
+
+ private:
+ // Creation parameters
+ Direct3DDevice9 *const device;
+
+ sw::PixelShader pixelShader;
+ };
+}
+
+#endif // D3D9_Direct3DPixelShader9_hpp
diff --git a/src/D3D9/Direct3DQuery9.cpp b/src/D3D9/Direct3DQuery9.cpp
new file mode 100644
index 0000000..c0f4323
--- /dev/null
+++ b/src/D3D9/Direct3DQuery9.cpp
@@ -0,0 +1,243 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3DQuery9.hpp"
+
+#include "Direct3DDevice9.hpp"
+#include "Timer.hpp"
+#include "Renderer.hpp"
+#include "Debug.hpp"
+
+#include <assert.h>
+
+namespace D3D9
+{
+ Direct3DQuery9::Direct3DQuery9(Direct3DDevice9 *device, D3DQUERYTYPE type) : device(device), type(type)
+ {
+ if(type == D3DQUERYTYPE_OCCLUSION)
+ {
+ query = new sw::Query();
+ }
+ else
+ {
+ query = 0;
+ }
+ }
+
+ Direct3DQuery9::~Direct3DQuery9()
+ {
+ if(query)
+ {
+ device->removeQuery(query);
+
+ delete query;
+ }
+ }
+
+ long Direct3DQuery9::QueryInterface(const IID &iid, void **object)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(iid == IID_IDirect3DQuery9 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long Direct3DQuery9::AddRef()
+ {
+ TRACE("");
+
+ return Unknown::AddRef();
+ }
+
+ unsigned long Direct3DQuery9::Release()
+ {
+ TRACE("");
+
+ return Unknown::Release();
+ }
+
+ long __stdcall Direct3DQuery9::GetDevice(IDirect3DDevice9 **device)
+ {
+ CriticalSection cs(this->device);
+
+ TRACE("");
+
+ if(!device)
+ {
+ return INVALIDCALL();
+ }
+
+ this->device->AddRef();
+ *device = this->device;
+
+ return D3D_OK;
+ }
+
+ D3DQUERYTYPE Direct3DQuery9::GetType()
+ {
+ CriticalSection cs(device);
+
+ return type;
+ }
+
+ unsigned long Direct3DQuery9::GetDataSize()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ switch(type)
+ {
+ case D3DQUERYTYPE_VCACHE: return sizeof(D3DDEVINFO_VCACHE);
+ case D3DQUERYTYPE_RESOURCEMANAGER: return sizeof(D3DDEVINFO_RESOURCEMANAGER);
+ case D3DQUERYTYPE_VERTEXSTATS: return sizeof(D3DDEVINFO_D3DVERTEXSTATS);
+ case D3DQUERYTYPE_EVENT: return sizeof(BOOL);
+ case D3DQUERYTYPE_OCCLUSION: return sizeof(DWORD);
+ case D3DQUERYTYPE_TIMESTAMP: return sizeof(UINT64);
+ case D3DQUERYTYPE_TIMESTAMPDISJOINT: return sizeof(BOOL);
+ case D3DQUERYTYPE_TIMESTAMPFREQ: return sizeof(UINT64);
+ case D3DQUERYTYPE_PIPELINETIMINGS: return sizeof(D3DDEVINFO_D3D9PIPELINETIMINGS);
+ case D3DQUERYTYPE_INTERFACETIMINGS: return sizeof(D3DDEVINFO_D3D9INTERFACETIMINGS);
+ case D3DQUERYTYPE_VERTEXTIMINGS: return sizeof(D3DDEVINFO_D3D9STAGETIMINGS);
+ case D3DQUERYTYPE_PIXELTIMINGS: return sizeof(D3DDEVINFO_D3D9PIPELINETIMINGS);
+ case D3DQUERYTYPE_BANDWIDTHTIMINGS: return sizeof(D3DDEVINFO_D3D9BANDWIDTHTIMINGS);
+ case D3DQUERYTYPE_CACHEUTILIZATION: return sizeof(D3DDEVINFO_D3D9CACHEUTILIZATION);
+ default:
+ ASSERT(false);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DQuery9::Issue(unsigned long flags)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END)
+ {
+ return INVALIDCALL();
+ }
+
+ switch(type)
+ {
+ case D3DQUERYTYPE_VCACHE: if(flags != D3DISSUE_END) return INVALIDCALL(); break;
+ case D3DQUERYTYPE_RESOURCEMANAGER: if(flags != D3DISSUE_END) return INVALIDCALL(); break;
+ case D3DQUERYTYPE_VERTEXSTATS: if(flags != D3DISSUE_END) return INVALIDCALL(); break;
+ case D3DQUERYTYPE_EVENT:
+ if(flags == D3DISSUE_END)
+ {
+ // device->renderer->synchronize(); // FIXME
+ }
+ else return INVALIDCALL();
+ break;
+ case D3DQUERYTYPE_OCCLUSION:
+ if(flags == D3DISSUE_BEGIN)
+ {
+ query->begin();
+ device->addQuery(query);
+ device->setOcclusionEnabled(true);
+ }
+ else // flags == D3DISSUE_END
+ {
+ query->end();
+ device->removeQuery(query);
+ device->setOcclusionEnabled(false);
+ }
+ break;
+ case D3DQUERYTYPE_TIMESTAMP: if(flags != D3DISSUE_END) return INVALIDCALL(); break;
+ case D3DQUERYTYPE_TIMESTAMPDISJOINT: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
+ case D3DQUERYTYPE_TIMESTAMPFREQ: if(flags != D3DISSUE_END) return INVALIDCALL(); break;
+ case D3DQUERYTYPE_PIPELINETIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
+ case D3DQUERYTYPE_INTERFACETIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
+ case D3DQUERYTYPE_VERTEXTIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
+ case D3DQUERYTYPE_PIXELTIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
+ case D3DQUERYTYPE_BANDWIDTHTIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
+ case D3DQUERYTYPE_CACHEUTILIZATION: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
+ default:
+ ASSERT(false);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DQuery9::GetData(void *data, unsigned long size, unsigned long flags)
+ {
+ CriticalSection cs(device);
+
+ TRACE("void *data = %p, unsigned long size = %d, unsigned long flags = %d", data, size, flags);
+
+ if(query && query->building)
+ {
+ return INVALIDCALL();
+ }
+
+ bool signaled = !query || query->reference == 0;
+
+ if(size && signaled)
+ {
+ if(!data)
+ {
+ return INVALIDCALL();
+ }
+
+ // FIXME: Check size
+
+ switch(type)
+ {
+ case D3DQUERYTYPE_VCACHE:
+ {
+ D3DDEVINFO_VCACHE vcache;
+
+ vcache.Pattern = 'CACH';
+ vcache.OptMethod = 1; // Vertex-cache based optimization
+ vcache.CacheSize = 16;
+ vcache.MagicNumber = 8;
+
+ *(D3DDEVINFO_VCACHE*)data = vcache;
+ }
+ break;
+ case D3DQUERYTYPE_RESOURCEMANAGER: UNIMPLEMENTED(); break;
+ case D3DQUERYTYPE_VERTEXSTATS: UNIMPLEMENTED(); break;
+ case D3DQUERYTYPE_EVENT: *(BOOL*)data = TRUE; break; // FIXME
+ case D3DQUERYTYPE_OCCLUSION:
+ *(DWORD*)data = query->data;
+ break;
+ case D3DQUERYTYPE_TIMESTAMP: *(UINT64*)data = sw::Timer::counter(); break; // FIXME: Verify behaviour
+ case D3DQUERYTYPE_TIMESTAMPDISJOINT: *(BOOL*)data = FALSE; break; // FIXME: Verify behaviour
+ case D3DQUERYTYPE_TIMESTAMPFREQ: *(UINT64*)data = sw::Timer::frequency(); break; // FIXME: Verify behaviour
+ case D3DQUERYTYPE_PIPELINETIMINGS: UNIMPLEMENTED(); break;
+ case D3DQUERYTYPE_INTERFACETIMINGS: UNIMPLEMENTED(); break;
+ case D3DQUERYTYPE_VERTEXTIMINGS: UNIMPLEMENTED(); break;
+ case D3DQUERYTYPE_PIXELTIMINGS: UNIMPLEMENTED(); break;
+ case D3DQUERYTYPE_BANDWIDTHTIMINGS: UNIMPLEMENTED(); break;
+ case D3DQUERYTYPE_CACHEUTILIZATION: UNIMPLEMENTED(); break;
+ default:
+ ASSERT(false);
+ }
+ }
+
+ return signaled ? S_OK : S_FALSE;
+ }
+}
diff --git a/src/D3D9/Direct3DQuery9.hpp b/src/D3D9/Direct3DQuery9.hpp
new file mode 100644
index 0000000..c5f51cf
--- /dev/null
+++ b/src/D3D9/Direct3DQuery9.hpp
@@ -0,0 +1,53 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Direct3DQuery9_hpp
+#define D3D9_Direct3DQuery9_hpp
+
+#include "Unknown.hpp"
+
+#include "Renderer.hpp"
+
+#include <d3d9.h>
+
+namespace D3D9
+{
+ class Direct3DDevice9;
+
+ class Direct3DQuery9 : public IDirect3DQuery9, public Unknown
+ {
+ public:
+ Direct3DQuery9(Direct3DDevice9 *device, D3DQUERYTYPE type);
+
+ virtual ~Direct3DQuery9();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // IDirect3DQuery9 methods
+ long __stdcall GetDevice(IDirect3DDevice9 **device);
+ D3DQUERYTYPE __stdcall GetType();
+ unsigned long __stdcall GetDataSize();
+ long __stdcall Issue(unsigned long flags);
+ long __stdcall GetData(void *data, unsigned long size, unsigned long flags);
+
+ private:
+ // Creation parameters
+ Direct3DDevice9 *const device;
+ const D3DQUERYTYPE type;
+
+ sw::Query *query;
+ };
+}
+
+#endif // D3D9_Direct3DQuery9_hpp
diff --git a/src/D3D9/Direct3DResource9.cpp b/src/D3D9/Direct3DResource9.cpp
new file mode 100644
index 0000000..94af0fb
--- /dev/null
+++ b/src/D3D9/Direct3DResource9.cpp
@@ -0,0 +1,239 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3DResource9.hpp"
+
+#include "Direct3DDevice9.hpp"
+#include "Debug.hpp"
+
+namespace D3D9
+{
+ unsigned int Direct3DResource9::memoryUsage = 0;
+
+ Direct3DResource9::PrivateData::PrivateData()
+ {
+ data = 0;
+ }
+
+ Direct3DResource9::PrivateData::PrivateData(const void *data, int size, bool managed)
+ {
+ this->size = size;
+ this->managed = managed;
+
+ this->data = (void*)new unsigned char[size];
+ memcpy(this->data, data, size);
+
+ if(managed)
+ {
+ ((IUnknown*)data)->AddRef();
+ }
+ }
+
+ Direct3DResource9::PrivateData &Direct3DResource9::PrivateData::operator=(const PrivateData &privateData)
+ {
+ size = privateData.size;
+ managed = privateData.managed;
+
+ if(data)
+ {
+ if(managed)
+ {
+ ((IUnknown*)data)->Release();
+ }
+
+ delete[] data;
+ }
+
+ data = (void*)new unsigned char[size];
+ memcpy(data, privateData.data, size);
+
+ return *this;
+ }
+
+ Direct3DResource9::PrivateData::~PrivateData()
+ {
+ if(data && managed)
+ {
+ ((IUnknown*)data)->Release();
+ }
+
+ delete[] data;
+ data = 0;
+ }
+
+ Direct3DResource9::Direct3DResource9(Direct3DDevice9 *device, D3DRESOURCETYPE type, D3DPOOL pool, unsigned int size) : device(device), type(type), pool(pool), size(size)
+ {
+ priority = 0;
+
+ if(pool == D3DPOOL_DEFAULT)
+ {
+ memoryUsage += size;
+ }
+ }
+
+ Direct3DResource9::~Direct3DResource9()
+ {
+ if(pool == D3DPOOL_DEFAULT)
+ {
+ memoryUsage -= size;
+ }
+ }
+
+ long Direct3DResource9::QueryInterface(const IID &iid, void **object)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(iid == IID_IDirect3DResource9 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long Direct3DResource9::AddRef()
+ {
+ TRACE("");
+
+ return Unknown::AddRef();
+ }
+
+ unsigned long Direct3DResource9::Release()
+ {
+ TRACE("");
+
+ return Unknown::Release();
+ }
+
+ long Direct3DResource9::GetDevice(IDirect3DDevice9 **device)
+ {
+ CriticalSection cs(this->device);
+
+ TRACE("");
+
+ if(!device)
+ {
+ return INVALIDCALL();
+ }
+
+ this->device->AddRef();
+ *device = this->device;
+
+ return D3D_OK;
+ }
+
+ long Direct3DResource9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ privateData[guid] = PrivateData(data, size, flags == D3DSPD_IUNKNOWN);
+
+ return D3D_OK;
+ }
+
+ long Direct3DResource9::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ Iterator result = privateData.find(guid);
+
+ if(result == privateData.end())
+ {
+ return NOTFOUND();
+ }
+
+ if(result->second.size > *size)
+ {
+ return MOREDATA();
+ }
+
+ memcpy(data, result->second.data, result->second.size);
+
+ return D3D_OK;
+ }
+
+ long Direct3DResource9::FreePrivateData(const GUID &guid)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ Iterator result = privateData.find(guid);
+
+ if(result == privateData.end())
+ {
+ return D3DERR_NOTFOUND;
+ }
+
+ privateData.erase(guid);
+
+ return D3D_OK;
+ }
+
+ unsigned long Direct3DResource9::SetPriority(unsigned long newPriority)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ unsigned long oldPriority = priority;
+ priority = newPriority;
+
+ return oldPriority;
+ }
+
+ unsigned long Direct3DResource9::GetPriority()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return priority;
+ }
+
+ void Direct3DResource9::PreLoad()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+ }
+
+ D3DRESOURCETYPE Direct3DResource9::GetType()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return type;
+ }
+
+ unsigned int Direct3DResource9::getMemoryUsage()
+ {
+ return memoryUsage;
+ }
+
+ D3DPOOL Direct3DResource9::getPool() const
+ {
+ return pool;
+ }
+}
\ No newline at end of file
diff --git a/src/D3D9/Direct3DResource9.hpp b/src/D3D9/Direct3DResource9.hpp
new file mode 100644
index 0000000..46d4c19
--- /dev/null
+++ b/src/D3D9/Direct3DResource9.hpp
@@ -0,0 +1,91 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Direct3DResource9_hpp
+#define D3D9_Direct3DResource9_hpp
+
+#include "Unknown.hpp"
+
+#include <d3d9.h>
+
+#include <map>
+
+namespace D3D9
+{
+ class Direct3DDevice9;
+
+ class Direct3DResource9 : public IDirect3DResource9, public Unknown
+ {
+ public:
+ Direct3DResource9(Direct3DDevice9 *device, D3DRESOURCETYPE type, D3DPOOL pool, unsigned int size);
+
+ virtual ~Direct3DResource9();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // IDirect3DResource9 methods
+ long __stdcall GetDevice(IDirect3DDevice9 **device);
+ long __stdcall SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags);
+ long __stdcall GetPrivateData(const GUID &guid, void *data, unsigned long *size);
+ long __stdcall FreePrivateData(const GUID &guid);
+ unsigned long __stdcall SetPriority(unsigned long newPriority);
+ unsigned long __stdcall GetPriority();
+ void __stdcall PreLoad();
+ D3DRESOURCETYPE __stdcall GetType();
+
+ // Internal methods
+ static unsigned int getMemoryUsage();
+ D3DPOOL getPool() const;
+
+ protected:
+ // Creation parameters
+ Direct3DDevice9 *const device;
+ const D3DRESOURCETYPE type;
+ const D3DPOOL pool;
+ const unsigned int size;
+
+ private:
+ unsigned long priority;
+
+ struct PrivateData
+ {
+ PrivateData();
+ PrivateData(const void *data, int size, bool managed);
+
+ ~PrivateData();
+
+ PrivateData &operator=(const PrivateData &privateData);
+
+ void *data;
+ unsigned long size;
+ bool managed; // IUnknown interface
+ };
+
+ struct CompareGUID
+ {
+ bool operator()(const GUID& left, const GUID& right) const
+ {
+ return memcmp(&left, &right, sizeof(GUID)) < 0;
+ }
+ };
+
+ typedef std::map<GUID, PrivateData, CompareGUID> PrivateDataMap;
+ typedef PrivateDataMap::iterator Iterator;
+ PrivateDataMap privateData;
+
+ static unsigned int memoryUsage;
+ };
+}
+
+#endif // D3D9_Direct3DResource9_hpp
diff --git a/src/D3D9/Direct3DStateBlock9.cpp b/src/D3D9/Direct3DStateBlock9.cpp
new file mode 100644
index 0000000..9c5d02a
--- /dev/null
+++ b/src/D3D9/Direct3DStateBlock9.cpp
@@ -0,0 +1,1342 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3DStateBlock9.hpp"
+
+#include "Direct3DDevice9.hpp"
+#include "Direct3DVertexDeclaration9.hpp"
+#include "Direct3DIndexBuffer9.hpp"
+#include "Direct3DVertexBuffer9.hpp"
+#include "Direct3DBaseTexture9.hpp"
+#include "Direct3DPixelShader9.hpp"
+#include "Direct3DVertexShader9.hpp"
+#include "Debug.hpp"
+
+#include <assert.h>
+
+namespace D3D9
+{
+ Direct3DStateBlock9::Direct3DStateBlock9(Direct3DDevice9 *device, D3DSTATEBLOCKTYPE type) : device(device), type(type)
+ {
+ vertexDeclaration = 0;
+
+ indexBuffer = 0;
+
+ for(int stream = 0; stream < 16; stream++)
+ {
+ streamSource[stream].vertexBuffer = 0;
+ }
+
+ for(int sampler = 0; sampler < 16 + 4; sampler++)
+ {
+ texture[sampler] = 0;
+ }
+
+ pixelShader = 0;
+ vertexShader = 0;
+
+ clear();
+
+ if(type == D3DSBT_PIXELSTATE || type == D3DSBT_ALL)
+ {
+ capturePixelRenderStates();
+ capturePixelTextureStates();
+ capturePixelSamplerStates();
+ capturePixelShaderStates();
+ }
+
+ if(type == D3DSBT_VERTEXSTATE || type == D3DSBT_ALL)
+ {
+ captureVertexRenderStates();
+ captureVertexSamplerStates();
+ captureVertexTextureStates();
+ captureNPatchMode();
+ captureLightStates();
+ captureVertexShaderStates();
+ captureStreamSourceFrequencies();
+ captureFVF();
+ captureVertexDeclaration();
+ }
+
+ if(type == D3DSBT_ALL) // Capture remaining states
+ {
+ captureTextures();
+ captureTexturePalette();
+ captureVertexStreams();
+ captureIndexBuffer();
+ captureViewport();
+ captureScissorRectangle();
+ captureTransforms();
+ captureTextureTransforms();
+ captureClippingPlanes();
+ captureMaterial();
+ }
+ }
+
+ Direct3DStateBlock9::~Direct3DStateBlock9()
+ {
+ clear();
+ }
+
+ long Direct3DStateBlock9::QueryInterface(const IID &iid, void **object)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(iid == IID_IDirect3DStateBlock9 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long Direct3DStateBlock9::AddRef()
+ {
+ TRACE("");
+
+ return Unknown::AddRef();
+ }
+
+ unsigned long Direct3DStateBlock9::Release()
+ {
+ TRACE("");
+
+ return Unknown::Release();
+ }
+
+ long Direct3DStateBlock9::Apply()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(device->isRecording())
+ {
+ return INVALIDCALL();
+ }
+
+ if(fvfCaptured)
+ {
+ device->SetFVF(FVF);
+ }
+
+ if(vertexDeclarationCaptured)
+ {
+ device->SetVertexDeclaration(vertexDeclaration);
+ }
+
+ if(indexBufferCaptured)
+ {
+ device->SetIndices(indexBuffer);
+ }
+
+ for(int state = D3DRS_ZENABLE; state <= D3DRS_BLENDOPALPHA; state++)
+ {
+ if(renderStateCaptured[state])
+ {
+ device->SetRenderState((D3DRENDERSTATETYPE)state, renderState[state]);
+ }
+ }
+
+ if(nPatchModeCaptured)
+ {
+ device->SetNPatchMode(nPatchMode);
+ }
+
+ for(int stage = 0; stage < 8; stage++)
+ {
+ for(int state = D3DTSS_COLOROP; state <= D3DTSS_CONSTANT; state++)
+ {
+ if(textureStageStateCaptured[stage][state])
+ {
+ device->SetTextureStageState(stage, (D3DTEXTURESTAGESTATETYPE)state, textureStageState[stage][state]);
+ }
+ }
+ }
+
+ for(int sampler = 0; sampler < 16 + 4; sampler++)
+ {
+ for(int state = D3DSAMP_ADDRESSU; state <= D3DSAMP_DMAPOFFSET; state++)
+ {
+ if(samplerStateCaptured[sampler][state])
+ {
+ int index = sampler < 16 ? sampler : D3DVERTEXTEXTURESAMPLER0 + (sampler - 16);
+ device->SetSamplerState(index, (D3DSAMPLERSTATETYPE)state, samplerState[sampler][state]);
+ }
+ }
+ }
+
+ for(int stream = 0; stream < 16; stream++)
+ {
+ if(streamSourceCaptured[stream])
+ {
+ device->SetStreamSource(stream, streamSource[stream].vertexBuffer, streamSource[stream].offset, streamSource[stream].stride);
+ }
+
+ if(streamSourceFrequencyCaptured[stream])
+ {
+ device->SetStreamSourceFreq(stream, streamSourceFrequency[stream]);
+ }
+ }
+
+ for(int sampler = 0; sampler < 16 + 4; sampler++)
+ {
+ if(textureCaptured[sampler])
+ {
+ int index = sampler < 16 ? sampler : D3DVERTEXTEXTURESAMPLER0 + (sampler - 16);
+ device->SetTexture(index, texture[sampler]);
+ }
+ }
+
+ for(int state = 0; state < 512; state++)
+ {
+ if(transformCaptured[state])
+ {
+ device->SetTransform((D3DTRANSFORMSTATETYPE)state, &transform[state]);
+ }
+ }
+
+ if(materialCaptured)
+ {
+ device->SetMaterial(&material);
+ }
+
+ for(int index = 0; index < 8; index++) // FIXME: Support unlimited index
+ {
+ if(lightCaptured[index])
+ {
+ device->SetLight(index, &light[index]);
+ }
+ }
+
+ for(int index = 0; index < 8; index++) // FIXME: Support unlimited index
+ {
+ if(lightEnableCaptured[index])
+ {
+ device->LightEnable(index, lightEnableState[index]);
+ }
+ }
+
+ if(pixelShaderCaptured)
+ {
+ device->SetPixelShader(pixelShader);
+ }
+
+ if(vertexShaderCaptured)
+ {
+ device->SetVertexShader(vertexShader);
+ }
+
+ if(viewportCaptured)
+ {
+ device->SetViewport(&viewport);
+ }
+
+ for(int i = 0; i < 224; i++)
+ {
+ if(*(int*)pixelShaderConstantF[i] != 0x80000000)
+ {
+ device->SetPixelShaderConstantF(i, pixelShaderConstantF[i], 1);
+ }
+ }
+
+ for(int i = 0; i < 16; i++)
+ {
+ if(pixelShaderConstantI[i][0] != 0x80000000)
+ {
+ device->SetPixelShaderConstantI(i, pixelShaderConstantI[i], 1);
+ }
+ }
+
+ for(int i = 0; i < 16; i++)
+ {
+ if(pixelShaderConstantB[i] != 0x80000000)
+ {
+ device->SetPixelShaderConstantB(i, &pixelShaderConstantB[i], 1);
+ }
+ }
+
+ for(int i = 0; i < 256; i++)
+ {
+ if(*(int*)vertexShaderConstantF[i] != 0x80000000)
+ {
+ device->SetVertexShaderConstantF(i, vertexShaderConstantF[i], 1);
+ }
+ }
+
+ for(int i = 0; i < 16; i++)
+ {
+ if(vertexShaderConstantI[i][0] != 0x80000000)
+ {
+ device->SetVertexShaderConstantI(i, vertexShaderConstantI[i], 1);
+ }
+ }
+
+ for(int i = 0; i < 16; i++)
+ {
+ if(vertexShaderConstantB[i] != 0x80000000)
+ {
+ device->SetVertexShaderConstantB(i, &vertexShaderConstantB[i], 1);
+ }
+ }
+
+ for(int index = 0; index < 6; index++)
+ {
+ if(clipPlaneCaptured[index])
+ {
+ device->SetClipPlane(index, clipPlane[index]);
+ }
+ }
+
+ if(scissorRectCaptured)
+ {
+ device->SetScissorRect(&scissorRect);
+ }
+
+ if(paletteNumberCaptured)
+ {
+ device->SetCurrentTexturePalette(paletteNumber);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DStateBlock9::Capture()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(fvfCaptured)
+ {
+ device->GetFVF(&FVF);
+ }
+
+ if(vertexDeclarationCaptured)
+ {
+ Direct3DVertexDeclaration9 *vertexDeclaration;
+ device->GetVertexDeclaration(reinterpret_cast<IDirect3DVertexDeclaration9**>(&vertexDeclaration));
+
+ if(vertexDeclaration)
+ {
+ vertexDeclaration->bind();
+ vertexDeclaration->Release();
+ }
+
+ if(this->vertexDeclaration)
+ {
+ this->vertexDeclaration->unbind();
+ }
+
+ this->vertexDeclaration = vertexDeclaration;
+ }
+
+ if(indexBufferCaptured)
+ {
+ Direct3DIndexBuffer9 *indexBuffer;
+ device->GetIndices(reinterpret_cast<IDirect3DIndexBuffer9**>(&indexBuffer));
+
+ if(indexBuffer)
+ {
+ indexBuffer->bind();
+ indexBuffer->Release();
+ }
+
+ if(this->indexBuffer)
+ {
+ this->indexBuffer->unbind();
+ }
+
+ this->indexBuffer = indexBuffer;
+ }
+
+ for(int state = 0; state < D3DRS_BLENDOPALPHA + 1; state++)
+ {
+ if(renderStateCaptured[state])
+ {
+ device->GetRenderState((D3DRENDERSTATETYPE)state, &renderState[state]);
+ }
+ }
+
+ if(nPatchModeCaptured)
+ {
+ nPatchMode = device->GetNPatchMode();
+ }
+
+ for(int stage = 0; stage < 8; stage++)
+ {
+ for(int state = 0; state < D3DTSS_CONSTANT + 1; state++)
+ {
+ if(textureStageStateCaptured[stage][state])
+ {
+ device->GetTextureStageState(stage, (D3DTEXTURESTAGESTATETYPE)state, &textureStageState[stage][state]);
+ }
+ }
+ }
+
+ for(int sampler = 0; sampler < 16 + 4; sampler++)
+ {
+ for(int state = 0; state < D3DSAMP_DMAPOFFSET + 1; state++)
+ {
+ if(samplerStateCaptured[sampler][state])
+ {
+ int index = sampler < 16 ? sampler : D3DVERTEXTEXTURESAMPLER0 + (sampler - 16);
+ device->GetSamplerState(index, (D3DSAMPLERSTATETYPE)state, &samplerState[sampler][state]);
+ }
+ }
+ }
+
+ for(int stream = 0; stream < 16; stream++)
+ {
+ if(streamSourceCaptured[stream])
+ {
+ Direct3DVertexBuffer9 *vertexBuffer;
+ device->GetStreamSource(stream, reinterpret_cast<IDirect3DVertexBuffer9**>(&vertexBuffer), &streamSource[stream].offset, &streamSource[stream].stride);
+
+ if(vertexBuffer)
+ {
+ vertexBuffer->bind();
+ vertexBuffer->Release();
+ }
+
+ if(streamSource[stream].vertexBuffer)
+ {
+ streamSource[stream].vertexBuffer->unbind();
+ }
+
+ streamSource[stream].vertexBuffer = vertexBuffer;
+ }
+
+ if(streamSourceFrequencyCaptured[stream])
+ {
+ device->GetStreamSourceFreq(stream, &streamSourceFrequency[stream]);
+ }
+ }
+
+ for(int sampler = 0; sampler < 16 + 4; sampler++)
+ {
+ if(textureCaptured[sampler])
+ {
+ Direct3DBaseTexture9 *texture;
+ int index = sampler < 16 ? sampler : D3DVERTEXTEXTURESAMPLER0 + (sampler - 16);
+ device->GetTexture(index, reinterpret_cast<IDirect3DBaseTexture9**>(&texture));
+
+ if(texture)
+ {
+ texture->bind();
+ texture->Release();
+ }
+
+ if(this->texture[sampler])
+ {
+ this->texture[sampler]->unbind();
+ }
+
+ this->texture[sampler] = texture;
+ }
+ }
+
+ for(int state = 0; state < 512; state++)
+ {
+ if(transformCaptured[state])
+ {
+ device->GetTransform((D3DTRANSFORMSTATETYPE)state, &transform[state]);
+ }
+ }
+
+ if(materialCaptured)
+ {
+ device->GetMaterial(&material);
+ }
+
+ for(int index = 0; index < 8; index++) // FIXME: Support unlimited index
+ {
+ if(lightCaptured[index])
+ {
+ device->GetLight(index, &light[index]);
+ }
+ }
+
+ for(int index = 0; index < 8; index++) // FIXME: Support unlimited index
+ {
+ if(lightEnableCaptured[index])
+ {
+ lightEnableState[index] = false;
+ device->GetLightEnable(index, &lightEnableState[index]);
+ }
+ }
+
+ if(pixelShaderCaptured)
+ {
+ Direct3DPixelShader9 *pixelShader;
+ device->GetPixelShader(reinterpret_cast<IDirect3DPixelShader9**>(&pixelShader));
+
+ if(pixelShader)
+ {
+ pixelShader->bind();
+ pixelShader->Release();
+ }
+
+ if(this->pixelShader)
+ {
+ this->pixelShader->unbind();
+ }
+
+ this->pixelShader = pixelShader;
+ }
+
+ if(vertexShaderCaptured)
+ {
+ Direct3DVertexShader9 *vertexShader;
+ device->GetVertexShader(reinterpret_cast<IDirect3DVertexShader9**>(&vertexShader));
+
+ if(vertexShader)
+ {
+ vertexShader->bind();
+ vertexShader->Release();
+ }
+
+ if(this->vertexShader)
+ {
+ this->vertexShader->unbind();
+ }
+
+ this->vertexShader = vertexShader;
+ }
+
+ if(viewportCaptured)
+ {
+ device->GetViewport(&viewport);
+ }
+
+ for(int i = 0; i < 224; i++)
+ {
+ if(*(int*)pixelShaderConstantF[i] != 0x80000000)
+ {
+ device->GetPixelShaderConstantF(i, pixelShaderConstantF[i], 1);
+ }
+ }
+
+ for(int i = 0; i < 16; i++)
+ {
+ if(pixelShaderConstantI[i][0] != 0x80000000)
+ {
+ device->GetPixelShaderConstantI(i, pixelShaderConstantI[i], 1);
+ }
+ }
+
+ for(int i = 0; i < 16; i++)
+ {
+ if(pixelShaderConstantB[i] != 0x80000000)
+ {
+ device->GetPixelShaderConstantB(i, &pixelShaderConstantB[i], 1);
+ }
+ }
+
+ for(int i = 0; i < 256; i++)
+ {
+ if(*(int*)vertexShaderConstantF[i] != 0x80000000)
+ {
+ device->GetVertexShaderConstantF(i, vertexShaderConstantF[i], 1);
+ }
+ }
+
+ for(int i = 0; i < 16; i++)
+ {
+ if(vertexShaderConstantI[i][0] != 0x80000000)
+ {
+ device->GetVertexShaderConstantI(i, vertexShaderConstantI[i], 1);
+ }
+ }
+
+ for(int i = 0; i < 16; i++)
+ {
+ if(vertexShaderConstantB[i] != 0x80000000)
+ {
+ device->GetVertexShaderConstantB(i, &vertexShaderConstantB[i], 1);
+ }
+ }
+
+ for(int index = 0; index < 6; index++)
+ {
+ if(clipPlaneCaptured[index])
+ {
+ device->GetClipPlane(index, clipPlane[index]);
+ }
+ }
+
+ if(scissorRectCaptured)
+ {
+ device->GetScissorRect(&scissorRect);
+ }
+
+ if(paletteNumberCaptured)
+ {
+ device->GetCurrentTexturePalette(&paletteNumber);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DStateBlock9::GetDevice(IDirect3DDevice9 **device)
+ {
+ CriticalSection cs(this->device);
+
+ TRACE("");
+
+ if(!device)
+ {
+ return INVALIDCALL();
+ }
+
+ this->device->AddRef();
+ *device = this->device;
+
+ return D3D_OK;
+ }
+
+ void Direct3DStateBlock9::lightEnable(unsigned long index, int enable)
+ {
+ if(index < 8)
+ {
+ lightEnableCaptured[index] = true;
+ lightEnableState[index] = enable;
+ }
+ else ASSERT(false); // FIXME: Support unlimited index
+ }
+
+ void Direct3DStateBlock9::setClipPlane(unsigned long index, const float *plane)
+ {
+ clipPlaneCaptured[index] = true;
+ clipPlane[index][0] = plane[0];
+ clipPlane[index][1] = plane[1];
+ clipPlane[index][2] = plane[2];
+ clipPlane[index][3] = plane[3];
+ }
+
+ void Direct3DStateBlock9::setCurrentTexturePalette(unsigned int paletteNumber)
+ {
+ paletteNumberCaptured = true;
+ this->paletteNumber = paletteNumber;
+ }
+
+ void Direct3DStateBlock9::setFVF(unsigned long FVF)
+ {
+ fvfCaptured = true;
+ this->FVF = FVF;
+ }
+
+ void Direct3DStateBlock9::setIndices(Direct3DIndexBuffer9 *indexBuffer)
+ {
+ if(indexBuffer) indexBuffer->bind();
+ if(this->indexBuffer) this->indexBuffer->unbind();
+
+ indexBufferCaptured = true;
+ this->indexBuffer = indexBuffer;
+ }
+
+ void Direct3DStateBlock9::setLight(unsigned long index, const D3DLIGHT9 *light)
+ {
+ if(index < 8)
+ {
+ lightCaptured[index] = true;
+ this->light[index] = *light;
+ }
+ else ASSERT(false); // FIXME: Support unlimited index
+ }
+
+ void Direct3DStateBlock9::setMaterial(const D3DMATERIAL9 *material)
+ {
+ materialCaptured = true;
+ this->material = *material;
+ }
+
+ void Direct3DStateBlock9::setNPatchMode(float segments)
+ {
+ nPatchModeCaptured = true;
+ nPatchMode = segments;
+ }
+
+ void Direct3DStateBlock9::setPixelShader(Direct3DPixelShader9 *pixelShader)
+ {
+ if(pixelShader) pixelShader->bind();
+ if(this->pixelShader) this->pixelShader->unbind();
+
+ pixelShaderCaptured = true;
+ this->pixelShader = pixelShader;
+ }
+
+ void Direct3DStateBlock9::setPixelShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count)
+ {
+ memcpy(&pixelShaderConstantB[startRegister], constantData, count * sizeof(int));
+ }
+
+ void Direct3DStateBlock9::setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
+ {
+ memcpy(pixelShaderConstantF[startRegister], constantData, count * sizeof(float[4]));
+ }
+
+ void Direct3DStateBlock9::setPixelShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count)
+ {
+ memcpy(pixelShaderConstantI[startRegister], constantData, count * sizeof(int[4]));
+ }
+
+ void Direct3DStateBlock9::setRenderState(D3DRENDERSTATETYPE state, unsigned long value)
+ {
+ renderStateCaptured[state] = true;
+ renderState[state] = value;
+ }
+
+ void Direct3DStateBlock9::setSamplerState(unsigned long index, D3DSAMPLERSTATETYPE state, unsigned long value)
+ {
+ unsigned int sampler = index < 16 ? index : (index - D3DVERTEXTEXTURESAMPLER0) + 16;
+
+ if(sampler >= 16 + 4)
+ {
+ return;
+ }
+
+ samplerStateCaptured[sampler][state] = true;
+ samplerState[sampler][state] = value;
+ }
+
+ void Direct3DStateBlock9::setScissorRect(const RECT *rect)
+ {
+ scissorRectCaptured = true;
+ scissorRect = *rect;
+ }
+
+ void Direct3DStateBlock9::setStreamSource(unsigned int stream, Direct3DVertexBuffer9 *vertexBuffer, unsigned int offset, unsigned int stride)
+ {
+ if(vertexBuffer) vertexBuffer->bind();
+ if(streamSource[stream].vertexBuffer) streamSource[stream].vertexBuffer->unbind();
+
+ streamSourceCaptured[stream] = true;
+ streamSource[stream].vertexBuffer = vertexBuffer;
+ streamSource[stream].offset = offset;
+ streamSource[stream].stride = stride;
+ }
+
+ void Direct3DStateBlock9::setStreamSourceFreq(unsigned int streamNumber, unsigned int divider)
+ {
+ streamSourceFrequencyCaptured[streamNumber] = true;
+ streamSourceFrequency[streamNumber] = divider;
+ }
+
+ void Direct3DStateBlock9::setTexture(unsigned long index, Direct3DBaseTexture9 *texture)
+ {
+ unsigned int sampler = index < 16 ? index : (index - D3DVERTEXTEXTURESAMPLER0) + 16;
+
+ if(sampler >= 16 + 4)
+ {
+ return;
+ }
+
+ if(texture) texture->bind();
+ if(this->texture[sampler]) this->texture[sampler]->unbind();
+
+ textureCaptured[sampler] = true;
+ this->texture[sampler] = texture;
+ }
+
+ void Direct3DStateBlock9::setTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long value)
+ {
+ textureStageStateCaptured[stage][type] = true;
+ textureStageState[stage][type] = value;
+ }
+
+ void Direct3DStateBlock9::setTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
+ {
+ transformCaptured[state] = true;
+ transform[state] = *matrix;
+ }
+
+ void Direct3DStateBlock9::setViewport(const D3DVIEWPORT9 *viewport)
+ {
+ viewportCaptured = true;
+ this->viewport = *viewport;
+ }
+
+ void Direct3DStateBlock9::setVertexDeclaration(Direct3DVertexDeclaration9 *vertexDeclaration)
+ {
+ if(vertexDeclaration) vertexDeclaration->bind();
+ if(this->vertexDeclaration) this->vertexDeclaration->unbind();
+
+ vertexDeclarationCaptured = true;
+ this->vertexDeclaration = vertexDeclaration;
+ }
+
+ void Direct3DStateBlock9::setVertexShader(Direct3DVertexShader9 *vertexShader)
+ {
+ if(vertexShader) vertexShader->bind();
+ if(this->vertexShader) this->vertexShader->unbind();
+
+ vertexShaderCaptured = true;
+ this->vertexShader = vertexShader;
+ }
+
+ void Direct3DStateBlock9::setVertexShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count)
+ {
+ memcpy(&vertexShaderConstantB[startRegister], constantData, count * sizeof(int));
+ }
+
+ void Direct3DStateBlock9::setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
+ {
+ memcpy(vertexShaderConstantF[startRegister], constantData, count * sizeof(float[4]));
+ }
+
+ void Direct3DStateBlock9::setVertexShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count)
+ {
+ memcpy(vertexShaderConstantI[startRegister], constantData, count * sizeof(int[4]));
+ }
+
+ void Direct3DStateBlock9::clear()
+ {
+ // Erase capture flags
+ fvfCaptured = false;
+ vertexDeclarationCaptured = false;
+
+ indexBufferCaptured = false;
+
+ for(int state = 0; state < D3DRS_BLENDOPALPHA + 1; state++)
+ {
+ renderStateCaptured[state] = false;
+ }
+
+ nPatchModeCaptured = false;
+
+ for(int stage = 0; stage < 8; stage++)
+ {
+ for(int state = 0; state < D3DTSS_CONSTANT + 1; state++)
+ {
+ textureStageStateCaptured[stage][state] = false;
+ }
+ }
+
+ for(int sampler = 0; sampler < 16 + 4; sampler++)
+ {
+ for(int state = 0; state < D3DSAMP_DMAPOFFSET + 1; state++)
+ {
+ samplerStateCaptured[sampler][state] = false;
+ }
+ }
+
+ for(int stream = 0; stream < 16; stream++)
+ {
+ streamSourceCaptured[stream] = false;
+ streamSourceFrequencyCaptured[stream] = false;
+ }
+
+ for(int sampler = 0; sampler < 16 + 4; sampler++)
+ {
+ textureCaptured[sampler] = false;
+ }
+
+ for(int state = 0; state < 512; state++)
+ {
+ transformCaptured[state] = false;
+ }
+
+ materialCaptured = false;
+
+ for(int index = 0; index < 8; index++) // FIXME: Support unlimited index
+ {
+ lightCaptured[index] = false;
+ }
+
+ for(int index = 0; index < 8; index++) // FIXME: Support unlimited index
+ {
+ lightEnableCaptured[index] = false;
+ }
+
+ scissorRectCaptured = false;
+
+ pixelShaderCaptured = false;
+ vertexShaderCaptured = false;
+
+ viewportCaptured = false;
+
+ for(int i = 0; i < 224; i++)
+ {
+ (int&)pixelShaderConstantF[i][0] = 0x80000000;
+ (int&)pixelShaderConstantF[i][1] = 0x80000000;
+ (int&)pixelShaderConstantF[i][2] = 0x80000000;
+ (int&)pixelShaderConstantF[i][3] = 0x80000000;
+ }
+
+ for(int i = 0; i < 256; i++)
+ {
+ (int&)vertexShaderConstantF[i][0] = 0x80000000;
+ (int&)vertexShaderConstantF[i][1] = 0x80000000;
+ (int&)vertexShaderConstantF[i][2] = 0x80000000;
+ (int&)vertexShaderConstantF[i][3] = 0x80000000;
+ }
+
+ for(int i = 0; i < 16; i++)
+ {
+ pixelShaderConstantI[i][0] = 0x80000000;
+ pixelShaderConstantI[i][1] = 0x80000000;
+ pixelShaderConstantI[i][2] = 0x80000000;
+ pixelShaderConstantI[i][3] = 0x80000000;
+
+ pixelShaderConstantB[i] = 0x80000000;
+
+ vertexShaderConstantI[i][0] = 0x80000000;
+ vertexShaderConstantI[i][1] = 0x80000000;
+ vertexShaderConstantI[i][2] = 0x80000000;
+ vertexShaderConstantI[i][3] = 0x80000000;
+
+ vertexShaderConstantB[i] = 0x80000000;
+ }
+
+ for(int index = 0; index < 6; index++)
+ {
+ clipPlaneCaptured[index] = false;
+ }
+
+ paletteNumberCaptured = false;
+
+ // unbind resources
+ if(vertexDeclaration)
+ {
+ vertexDeclaration->unbind();
+ vertexDeclaration = 0;
+ }
+
+ if(indexBuffer)
+ {
+ indexBuffer->unbind();
+ indexBuffer = 0;
+ }
+
+ for(int stream = 0; stream < 16; stream++)
+ {
+ if(streamSource[stream].vertexBuffer)
+ {
+ streamSource[stream].vertexBuffer->unbind();
+ streamSource[stream].vertexBuffer = 0;
+ }
+ }
+
+ for(int sampler = 0; sampler < 16 + 4; sampler++)
+ {
+ if(texture[sampler])
+ {
+ texture[sampler]->unbind();
+ texture[sampler] = 0;
+ }
+ }
+
+ if(pixelShader)
+ {
+ pixelShader->unbind();
+ pixelShader = 0;
+ }
+
+ if(vertexShader)
+ {
+ vertexShader->unbind();
+ vertexShader = 0;
+ }
+ }
+
+ void Direct3DStateBlock9::captureRenderState(D3DRENDERSTATETYPE state)
+ {
+ device->GetRenderState(state, &renderState[state]);
+ renderStateCaptured[state] = true;
+ }
+
+ void Direct3DStateBlock9::captureSamplerState(unsigned long index, D3DSAMPLERSTATETYPE state)
+ {
+ if(index < 16)
+ {
+ device->GetSamplerState(index, state, &samplerState[index][state]);
+ samplerStateCaptured[index][state] = true;
+ }
+ else if(index >= D3DVERTEXTEXTURESAMPLER0)
+ {
+ unsigned int sampler = 16 + (index - D3DVERTEXTEXTURESAMPLER0);
+
+ device->GetSamplerState(index, state, &samplerState[sampler][state]);
+ samplerStateCaptured[sampler][state] = true;
+ }
+ }
+
+ void Direct3DStateBlock9::captureTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type)
+ {
+ device->GetTextureStageState(stage, type, &textureStageState[stage][type]);
+ textureStageStateCaptured[stage][type] = true;
+ }
+
+ void Direct3DStateBlock9::captureTransform(D3DTRANSFORMSTATETYPE state)
+ {
+ device->GetTransform(state, &transform[state]);
+ transformCaptured[state] = true;
+ }
+
+ void Direct3DStateBlock9::capturePixelRenderStates()
+ {
+ captureRenderState(D3DRS_ZENABLE);
+ captureRenderState(D3DRS_FILLMODE);
+ captureRenderState(D3DRS_SHADEMODE);
+ captureRenderState(D3DRS_ZWRITEENABLE);
+ captureRenderState(D3DRS_ALPHATESTENABLE);
+ captureRenderState(D3DRS_LASTPIXEL);
+ captureRenderState(D3DRS_SRCBLEND);
+ captureRenderState(D3DRS_DESTBLEND);
+ captureRenderState(D3DRS_ZFUNC);
+ captureRenderState(D3DRS_ALPHAREF);
+ captureRenderState(D3DRS_ALPHAFUNC);
+ captureRenderState(D3DRS_DITHERENABLE);
+ captureRenderState(D3DRS_FOGSTART);
+ captureRenderState(D3DRS_FOGEND);
+ captureRenderState(D3DRS_FOGDENSITY);
+ captureRenderState(D3DRS_ALPHABLENDENABLE);
+ captureRenderState(D3DRS_DEPTHBIAS);
+ captureRenderState(D3DRS_STENCILENABLE);
+ captureRenderState(D3DRS_STENCILFAIL);
+ captureRenderState(D3DRS_STENCILZFAIL);
+ captureRenderState(D3DRS_STENCILPASS);
+ captureRenderState(D3DRS_STENCILFUNC);
+ captureRenderState(D3DRS_STENCILREF);
+ captureRenderState(D3DRS_STENCILMASK);
+ captureRenderState(D3DRS_STENCILWRITEMASK);
+ captureRenderState(D3DRS_TEXTUREFACTOR);
+ captureRenderState(D3DRS_WRAP0);
+ captureRenderState(D3DRS_WRAP1);
+ captureRenderState(D3DRS_WRAP2);
+ captureRenderState(D3DRS_WRAP3);
+ captureRenderState(D3DRS_WRAP4);
+ captureRenderState(D3DRS_WRAP5);
+ captureRenderState(D3DRS_WRAP6);
+ captureRenderState(D3DRS_WRAP7);
+ captureRenderState(D3DRS_WRAP8);
+ captureRenderState(D3DRS_WRAP9);
+ captureRenderState(D3DRS_WRAP10);
+ captureRenderState(D3DRS_WRAP11);
+ captureRenderState(D3DRS_WRAP12);
+ captureRenderState(D3DRS_WRAP13);
+ captureRenderState(D3DRS_WRAP14);
+ captureRenderState(D3DRS_WRAP15);
+ captureRenderState(D3DRS_COLORWRITEENABLE);
+ captureRenderState(D3DRS_BLENDOP);
+ captureRenderState(D3DRS_SCISSORTESTENABLE);
+ captureRenderState(D3DRS_SLOPESCALEDEPTHBIAS);
+ captureRenderState(D3DRS_ANTIALIASEDLINEENABLE);
+ captureRenderState(D3DRS_TWOSIDEDSTENCILMODE);
+ captureRenderState(D3DRS_CCW_STENCILFAIL);
+ captureRenderState(D3DRS_CCW_STENCILZFAIL);
+ captureRenderState(D3DRS_CCW_STENCILPASS);
+ captureRenderState(D3DRS_CCW_STENCILFUNC);
+ captureRenderState(D3DRS_COLORWRITEENABLE1);
+ captureRenderState(D3DRS_COLORWRITEENABLE2);
+ captureRenderState(D3DRS_COLORWRITEENABLE3);
+ captureRenderState(D3DRS_BLENDFACTOR);
+ captureRenderState(D3DRS_SRGBWRITEENABLE);
+ captureRenderState(D3DRS_SEPARATEALPHABLENDENABLE);
+ captureRenderState(D3DRS_SRCBLENDALPHA);
+ captureRenderState(D3DRS_DESTBLENDALPHA);
+ captureRenderState(D3DRS_BLENDOPALPHA);
+ }
+
+ void Direct3DStateBlock9::capturePixelTextureStates()
+ {
+ for(int stage = 0; stage < 8; stage++)
+ {
+ captureTextureStageState(stage, D3DTSS_COLOROP);
+ captureTextureStageState(stage, D3DTSS_COLORARG1);
+ captureTextureStageState(stage, D3DTSS_COLORARG2);
+ captureTextureStageState(stage, D3DTSS_ALPHAOP);
+ captureTextureStageState(stage, D3DTSS_ALPHAARG1);
+ captureTextureStageState(stage, D3DTSS_ALPHAARG2);
+ captureTextureStageState(stage, D3DTSS_BUMPENVMAT00);
+ captureTextureStageState(stage, D3DTSS_BUMPENVMAT01);
+ captureTextureStageState(stage, D3DTSS_BUMPENVMAT10);
+ captureTextureStageState(stage, D3DTSS_BUMPENVMAT11);
+ captureTextureStageState(stage, D3DTSS_TEXCOORDINDEX);
+ captureTextureStageState(stage, D3DTSS_BUMPENVLSCALE);
+ captureTextureStageState(stage, D3DTSS_BUMPENVLOFFSET);
+ captureTextureStageState(stage, D3DTSS_TEXTURETRANSFORMFLAGS);
+ captureTextureStageState(stage, D3DTSS_COLORARG0);
+ captureTextureStageState(stage, D3DTSS_ALPHAARG0);
+ captureTextureStageState(stage, D3DTSS_RESULTARG);
+ }
+ }
+
+ void Direct3DStateBlock9::capturePixelSamplerStates()
+ {
+ for(int sampler = 0; sampler <= D3DVERTEXTEXTURESAMPLER3; sampler++)
+ {
+ captureSamplerState(sampler, D3DSAMP_ADDRESSU);
+ captureSamplerState(sampler, D3DSAMP_ADDRESSV);
+ captureSamplerState(sampler, D3DSAMP_ADDRESSW);
+ captureSamplerState(sampler, D3DSAMP_BORDERCOLOR);
+ captureSamplerState(sampler, D3DSAMP_MAGFILTER);
+ captureSamplerState(sampler, D3DSAMP_MINFILTER);
+ captureSamplerState(sampler, D3DSAMP_MIPFILTER);
+ captureSamplerState(sampler, D3DSAMP_MIPMAPLODBIAS);
+ captureSamplerState(sampler, D3DSAMP_MAXMIPLEVEL);
+ captureSamplerState(sampler, D3DSAMP_MAXANISOTROPY);
+ captureSamplerState(sampler, D3DSAMP_SRGBTEXTURE);
+ captureSamplerState(sampler, D3DSAMP_ELEMENTINDEX);
+ }
+ }
+
+ void Direct3DStateBlock9::capturePixelShaderStates()
+ {
+ pixelShaderCaptured = true;
+ device->GetPixelShader(reinterpret_cast<IDirect3DPixelShader9**>(&pixelShader));
+
+ if(pixelShader)
+ {
+ pixelShader->bind();
+ pixelShader->Release();
+ }
+
+ device->GetPixelShaderConstantF(0, pixelShaderConstantF[0], 32);
+ device->GetPixelShaderConstantI(0, pixelShaderConstantI[0], 16);
+ device->GetPixelShaderConstantB(0, pixelShaderConstantB, 16);
+ }
+
+ void Direct3DStateBlock9::captureVertexRenderStates()
+ {
+ captureRenderState(D3DRS_CULLMODE);
+ captureRenderState(D3DRS_FOGENABLE);
+ captureRenderState(D3DRS_FOGCOLOR);
+ captureRenderState(D3DRS_FOGTABLEMODE);
+ captureRenderState(D3DRS_FOGSTART);
+ captureRenderState(D3DRS_FOGEND);
+ captureRenderState(D3DRS_FOGDENSITY);
+ captureRenderState(D3DRS_RANGEFOGENABLE);
+ captureRenderState(D3DRS_AMBIENT);
+ captureRenderState(D3DRS_COLORVERTEX);
+ captureRenderState(D3DRS_FOGVERTEXMODE);
+ captureRenderState(D3DRS_CLIPPING);
+ captureRenderState(D3DRS_LIGHTING);
+ captureRenderState(D3DRS_LOCALVIEWER);
+ captureRenderState(D3DRS_EMISSIVEMATERIALSOURCE);
+ captureRenderState(D3DRS_AMBIENTMATERIALSOURCE);
+ captureRenderState(D3DRS_DIFFUSEMATERIALSOURCE);
+ captureRenderState(D3DRS_SPECULARMATERIALSOURCE);
+ captureRenderState(D3DRS_VERTEXBLEND);
+ captureRenderState(D3DRS_CLIPPLANEENABLE);
+ captureRenderState(D3DRS_POINTSIZE);
+ captureRenderState(D3DRS_POINTSIZE_MIN);
+ captureRenderState(D3DRS_POINTSPRITEENABLE);
+ captureRenderState(D3DRS_POINTSCALEENABLE);
+ captureRenderState(D3DRS_POINTSCALE_A);
+ captureRenderState(D3DRS_POINTSCALE_B);
+ captureRenderState(D3DRS_POINTSCALE_C);
+ captureRenderState(D3DRS_MULTISAMPLEANTIALIAS);
+ captureRenderState(D3DRS_MULTISAMPLEMASK);
+ captureRenderState(D3DRS_PATCHEDGESTYLE);
+ captureRenderState(D3DRS_POINTSIZE_MAX);
+ captureRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE);
+ captureRenderState(D3DRS_TWEENFACTOR);
+ captureRenderState(D3DRS_POSITIONDEGREE);
+ captureRenderState(D3DRS_NORMALDEGREE);
+ captureRenderState(D3DRS_MINTESSELLATIONLEVEL);
+ captureRenderState(D3DRS_MAXTESSELLATIONLEVEL);
+ captureRenderState(D3DRS_ADAPTIVETESS_X);
+ captureRenderState(D3DRS_ADAPTIVETESS_Y);
+ captureRenderState(D3DRS_ADAPTIVETESS_Z);
+ captureRenderState(D3DRS_ADAPTIVETESS_W);
+ captureRenderState(D3DRS_ENABLEADAPTIVETESSELLATION);
+ captureRenderState(D3DRS_NORMALIZENORMALS);
+ captureRenderState(D3DRS_SPECULARENABLE);
+ captureRenderState(D3DRS_SHADEMODE);
+ }
+
+ void Direct3DStateBlock9::captureVertexSamplerStates()
+ {
+ for(int sampler = 0; sampler <= D3DVERTEXTEXTURESAMPLER3; sampler++)
+ {
+ captureSamplerState(sampler, D3DSAMP_DMAPOFFSET);
+ }
+ }
+
+ void Direct3DStateBlock9::captureVertexTextureStates()
+ {
+ for(int stage = 0; stage < 8; stage++)
+ {
+ captureTextureStageState(stage, D3DTSS_TEXCOORDINDEX);
+ captureTextureStageState(stage, D3DTSS_TEXTURETRANSFORMFLAGS);
+ }
+ }
+
+ void Direct3DStateBlock9::captureNPatchMode()
+ {
+ nPatchMode = device->GetNPatchMode();
+ nPatchModeCaptured = true;
+ }
+
+ void Direct3DStateBlock9::captureLightStates()
+ {
+ for(int index = 0; index < 8; index++) // FIXME: Support unlimited index
+ {
+ long result = device->GetLight(index, &light[index]);
+ lightCaptured[index] = SUCCEEDED(result);
+ }
+
+ for(int index = 0; index < 8; index++) // FIXME: Support unlimited index
+ {
+ lightEnableState[index] = false;
+ long result = device->GetLightEnable(index, &lightEnableState[index]);
+ lightEnableCaptured[index] = SUCCEEDED(result);
+ }
+ }
+
+ void Direct3DStateBlock9::captureVertexShaderStates()
+ {
+ vertexShaderCaptured = true;
+ device->GetVertexShader(reinterpret_cast<IDirect3DVertexShader9**>(&vertexShader));
+
+ if(vertexShader)
+ {
+ vertexShader->bind();
+ vertexShader->Release();
+ }
+
+ device->GetVertexShaderConstantF(0, vertexShaderConstantF[0], 256);
+ device->GetVertexShaderConstantI(0, vertexShaderConstantI[0], 16);
+ device->GetVertexShaderConstantB(0, vertexShaderConstantB, 16);
+ }
+
+ void Direct3DStateBlock9::captureStreamSourceFrequencies()
+ {
+ for(int stream = 0; stream < 16; stream++)
+ {
+ streamSourceFrequencyCaptured[stream] = true;
+ device->GetStreamSourceFreq(stream, &streamSourceFrequency[stream]);
+ }
+ }
+
+ void Direct3DStateBlock9::captureFVF()
+ {
+ device->GetFVF(&FVF);
+ fvfCaptured = true;
+ }
+
+ void Direct3DStateBlock9::captureVertexDeclaration()
+ {
+ vertexDeclarationCaptured = true;
+ device->GetVertexDeclaration(reinterpret_cast<IDirect3DVertexDeclaration9**>(&vertexDeclaration));
+
+ if(vertexDeclaration)
+ {
+ vertexDeclaration->bind();
+ vertexDeclaration->Release();
+ }
+ }
+
+ void Direct3DStateBlock9::captureTextures()
+ {
+ for(int sampler = 0; sampler < 16 + 4; sampler++)
+ {
+ textureCaptured[sampler] = true;
+ int index = sampler < 16 ? sampler : D3DVERTEXTEXTURESAMPLER0 + (sampler - 16);
+ device->GetTexture(index, reinterpret_cast<IDirect3DBaseTexture9**>(&texture[sampler]));
+
+ if(texture[sampler])
+ {
+ texture[sampler]->bind();
+ texture[sampler]->Release();
+ }
+ }
+ }
+
+ void Direct3DStateBlock9::captureTexturePalette()
+ {
+ paletteNumberCaptured = true;
+ device->GetCurrentTexturePalette(&paletteNumber);
+ }
+
+ void Direct3DStateBlock9::captureVertexStreams()
+ {
+ for(int stream = 0; stream < 16; stream++)
+ {
+ streamSourceCaptured[stream] = true;
+ device->GetStreamSource(stream, reinterpret_cast<IDirect3DVertexBuffer9**>(&streamSource[stream].vertexBuffer), &streamSource[stream].offset, &streamSource[stream].stride);
+
+ if(streamSource[stream].vertexBuffer)
+ {
+ streamSource[stream].vertexBuffer->bind();
+ streamSource[stream].vertexBuffer->Release();
+ }
+ }
+ }
+
+ void Direct3DStateBlock9::captureIndexBuffer()
+ {
+ indexBufferCaptured = true;
+ device->GetIndices(reinterpret_cast<IDirect3DIndexBuffer9**>(&indexBuffer));
+
+ if(indexBuffer)
+ {
+ indexBuffer->bind();
+ indexBuffer->Release();
+ }
+ }
+
+ void Direct3DStateBlock9::captureViewport()
+ {
+ device->GetViewport(&viewport);
+ viewportCaptured = true;
+ }
+
+ void Direct3DStateBlock9::captureScissorRectangle()
+ {
+ device->GetScissorRect(&scissorRect);
+ scissorRectCaptured = true;
+ }
+
+ void Direct3DStateBlock9::captureTransforms()
+ {
+ captureTransform(D3DTS_VIEW);
+ captureTransform(D3DTS_PROJECTION);
+ captureTransform(D3DTS_WORLD);
+ }
+
+ void Direct3DStateBlock9::captureTextureTransforms()
+ {
+ captureTransform(D3DTS_TEXTURE0);
+ captureTransform(D3DTS_TEXTURE1);
+ captureTransform(D3DTS_TEXTURE2);
+ captureTransform(D3DTS_TEXTURE3);
+ captureTransform(D3DTS_TEXTURE4);
+ captureTransform(D3DTS_TEXTURE5);
+ captureTransform(D3DTS_TEXTURE6);
+ captureTransform(D3DTS_TEXTURE7);
+ }
+
+ void Direct3DStateBlock9::captureClippingPlanes()
+ {
+ for(int index = 0; index < 6; index++)
+ {
+ device->GetClipPlane(index, (float*)&clipPlane[index]);
+ clipPlaneCaptured[index] = true;
+ }
+ }
+
+ void Direct3DStateBlock9::captureMaterial()
+ {
+ device->GetMaterial(&material);
+ materialCaptured = true;
+ }
+}
diff --git a/src/D3D9/Direct3DStateBlock9.hpp b/src/D3D9/Direct3DStateBlock9.hpp
new file mode 100644
index 0000000..5ae4e0b
--- /dev/null
+++ b/src/D3D9/Direct3DStateBlock9.hpp
@@ -0,0 +1,195 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Direct3DStateBlock9_hpp
+#define D3D9_Direct3DStateBlock9_hpp
+
+#include "Unknown.hpp"
+
+#include <vector>
+
+#include <d3d9.h>
+
+namespace D3D9
+{
+ class Direct3DDevice9;
+ class Direct3DVertexDeclaration9;
+ class Direct3DIndexBuffer9;
+ class Direct3DVertexBuffer9;
+ class Direct3DBaseTexture9;
+ class Direct3DPixelShader9;
+ class Direct3DVertexShader9;
+
+ class Direct3DStateBlock9 : public IDirect3DStateBlock9, public Unknown
+ {
+ public:
+ Direct3DStateBlock9(Direct3DDevice9 *device, D3DSTATEBLOCKTYPE type);
+
+ virtual ~Direct3DStateBlock9();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // IDirect3DStateBlock9 methods
+ long __stdcall Apply();
+ long __stdcall Capture();
+ long __stdcall GetDevice(IDirect3DDevice9 **device);
+
+ // Internal methods
+ void lightEnable(unsigned long index, int enable);
+ void setClipPlane(unsigned long index, const float *plane);
+ void setCurrentTexturePalette(unsigned int paletteNumber);
+ void setFVF(unsigned long FVF);
+ void setIndices(Direct3DIndexBuffer9 *indexData);
+ void setLight(unsigned long index, const D3DLIGHT9 *light);
+ void setMaterial(const D3DMATERIAL9 *material);
+ void setNPatchMode(float segments);
+ void setPixelShader(Direct3DPixelShader9 *shader);
+ void setPixelShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count);
+ void setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
+ void setPixelShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count);
+ void setRenderState(D3DRENDERSTATETYPE state, unsigned long value);
+ void setSamplerState(unsigned long index, D3DSAMPLERSTATETYPE state, unsigned long value);
+ void setScissorRect(const RECT *rect);
+ void setStreamSource(unsigned int stream, Direct3DVertexBuffer9 *data, unsigned int offset, unsigned int stride);
+ void setStreamSourceFreq(unsigned int streamNumber, unsigned int divider);
+ void setTexture(unsigned long index, Direct3DBaseTexture9 *texture);
+ void setTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long value);
+ void setTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix);
+ void setViewport(const D3DVIEWPORT9 *viewport);
+ void setVertexDeclaration(Direct3DVertexDeclaration9 *declaration);
+ void setVertexShader(Direct3DVertexShader9 *shader);
+ void setVertexShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count);
+ void setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
+ void setVertexShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count);
+
+ private:
+ // Individual states
+ void captureRenderState(D3DRENDERSTATETYPE state);
+ void captureSamplerState(unsigned long index, D3DSAMPLERSTATETYPE state);
+ void captureTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type);
+ void captureTransform(D3DTRANSFORMSTATETYPE state);
+
+ // Pixel states
+ void capturePixelRenderStates();
+ void capturePixelTextureStates();
+ void capturePixelSamplerStates();
+ void capturePixelShaderStates();
+
+ // Vertex states
+ void captureVertexRenderStates();
+ void captureVertexSamplerStates();
+ void captureVertexTextureStates();
+ void captureNPatchMode();
+ void captureLightStates();
+ void captureVertexShaderStates();
+ void captureStreamSourceFrequencies();
+ void captureVertexDeclaration();
+ void captureFVF();
+
+ // All (remaining) states
+ void captureTextures();
+ void captureTexturePalette();
+ void captureVertexStreams();
+ void captureIndexBuffer();
+ void captureViewport();
+ void captureScissorRectangle();
+ void captureTransforms();
+ void captureTextureTransforms();
+ void captureClippingPlanes();
+ void captureMaterial();
+
+ // Creation parameters
+ Direct3DDevice9 *const device;
+ const D3DSTATEBLOCKTYPE type;
+
+ // State data
+ bool vertexDeclarationCaptured;
+ Direct3DVertexDeclaration9 *vertexDeclaration;
+
+ bool fvfCaptured;
+ unsigned long FVF;
+
+ bool indexBufferCaptured;
+ Direct3DIndexBuffer9 *indexBuffer;
+
+ bool renderStateCaptured[D3DRS_BLENDOPALPHA + 1];
+ unsigned long renderState[D3DRS_BLENDOPALPHA + 1];
+
+ bool nPatchModeCaptured;
+ float nPatchMode;
+
+ bool textureStageStateCaptured[8][D3DTSS_CONSTANT + 1];
+ unsigned long textureStageState[8][D3DTSS_CONSTANT + 1];
+
+ bool samplerStateCaptured[16 + 4][D3DSAMP_DMAPOFFSET + 1];
+ unsigned long samplerState[16 + 4][D3DSAMP_DMAPOFFSET + 1];
+
+ bool streamSourceCaptured[16];
+ struct StreamSource
+ {
+ Direct3DVertexBuffer9 *vertexBuffer;
+ unsigned int offset;
+ unsigned int stride;
+ };
+ StreamSource streamSource[16];
+
+ bool streamSourceFrequencyCaptured[16];
+ unsigned int streamSourceFrequency[16];
+
+ bool textureCaptured[16 + 4];
+ Direct3DBaseTexture9 *texture[16 + 4];
+
+ bool transformCaptured[512];
+ D3DMATRIX transform[512];
+
+ bool materialCaptured;
+ D3DMATERIAL9 material;
+
+ bool lightCaptured[8]; // FIXME: Unlimited index
+ D3DLIGHT9 light[8];
+
+ bool lightEnableCaptured[8]; // FIXME: Unlimited index
+ int lightEnableState[8];
+
+ bool pixelShaderCaptured;
+ Direct3DPixelShader9 *pixelShader;
+
+ bool vertexShaderCaptured;
+ Direct3DVertexShader9 *vertexShader;
+
+ bool viewportCaptured;
+ D3DVIEWPORT9 viewport;
+
+ float pixelShaderConstantF[224][4];
+ int pixelShaderConstantI[16][4];
+ int pixelShaderConstantB[16];
+
+ float vertexShaderConstantF[256][4];
+ int vertexShaderConstantI[16][4];
+ int vertexShaderConstantB[16];
+
+ bool clipPlaneCaptured[6];
+ float clipPlane[6][4];
+
+ bool scissorRectCaptured;
+ RECT scissorRect;
+
+ bool paletteNumberCaptured;
+ unsigned int paletteNumber;
+
+ void clear();
+ };
+}
+
+#endif // D3D9_Direct3DStateBlock9_hpp
diff --git a/src/D3D9/Direct3DSurface9.cpp b/src/D3D9/Direct3DSurface9.cpp
new file mode 100644
index 0000000..ee4d152
--- /dev/null
+++ b/src/D3D9/Direct3DSurface9.cpp
@@ -0,0 +1,404 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3DSurface9.hpp"
+
+#include "Direct3DDevice9.hpp"
+#include "Direct3DBaseTexture9.hpp"
+#include "Capabilities.hpp"
+#include "Resource.hpp"
+#include "Debug.hpp"
+
+#include <malloc.h>
+#include <assert.h>
+
+extern bool quadLayoutEnabled;
+
+namespace D3D9
+{
+ sw::Resource *getParentResource(Unknown *container)
+ {
+ Direct3DBaseTexture9 *baseTexture = dynamic_cast<Direct3DBaseTexture9*>(container);
+
+ if(baseTexture)
+ {
+ return baseTexture->getResource();
+ }
+
+ return 0;
+ }
+
+ int sampleCount(D3DMULTISAMPLE_TYPE multiSample, unsigned int quality)
+ {
+ if(multiSample == D3DMULTISAMPLE_NONMASKABLE)
+ {
+ switch(quality)
+ {
+ case 0: return 2;
+ case 1: return 4;
+ case 2: return 8;
+ case 3: return 16;
+ }
+ }
+ else if(multiSample == D3DMULTISAMPLE_2_SAMPLES)
+ {
+ return 2;
+ }
+ else if(multiSample == D3DMULTISAMPLE_4_SAMPLES)
+ {
+ return 4;
+ }
+ else if(multiSample == D3DMULTISAMPLE_8_SAMPLES)
+ {
+ return 8;
+ }
+ else if(multiSample == D3DMULTISAMPLE_16_SAMPLES)
+ {
+ return 16;
+ }
+
+ return 1;
+ }
+
+ bool isLockable(D3DPOOL pool, unsigned long usage, bool lockableOverride)
+ {
+ return (pool != D3DPOOL_DEFAULT) || (usage & D3DUSAGE_DYNAMIC) || lockableOverride;
+ }
+
+ Direct3DSurface9::Direct3DSurface9(Direct3DDevice9 *device, Unknown *container, int width, int height, D3DFORMAT format, D3DPOOL pool, D3DMULTISAMPLE_TYPE multiSample, unsigned int quality, bool lockableOverride, unsigned long usage) : Direct3DResource9(device, D3DRTYPE_SURFACE, pool, memoryUsage(width, height, format)), Surface(getParentResource(container), width, height, sampleCount(multiSample, quality), translateFormat(format), isLockable(pool, usage, lockableOverride), (usage & D3DUSAGE_RENDERTARGET) || (usage & D3DUSAGE_DEPTHSTENCIL)), container(container), width(width), height(height), format(format), pool(pool), multiSample(multiSample), quality(quality), lockable(isLockable(pool, usage, lockableOverride)), usage(usage)
+ {
+ parentTexture = dynamic_cast<Direct3DBaseTexture9*>(container);
+ }
+
+ Direct3DSurface9::~Direct3DSurface9()
+ {
+ }
+
+ long Direct3DSurface9::QueryInterface(const IID &iid, void **object)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(iid == IID_IDirect3DSurface9 ||
+ iid == IID_IDirect3DResource9 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long Direct3DSurface9::AddRef()
+ {
+ TRACE("");
+
+ if(parentTexture)
+ {
+ return parentTexture->AddRef();
+ }
+
+ return Direct3DResource9::AddRef();
+ }
+
+ unsigned long Direct3DSurface9::Release()
+ {
+ TRACE("");
+
+ if(parentTexture)
+ {
+ return parentTexture->Release();
+ }
+
+ return Direct3DResource9::Release();
+ }
+
+ long Direct3DSurface9::FreePrivateData(const GUID &guid)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::FreePrivateData(guid);
+ }
+
+ long Direct3DSurface9::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::GetPrivateData(guid, data, size);
+ }
+
+ void Direct3DSurface9::PreLoad()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ Direct3DResource9::PreLoad();
+ }
+
+ long Direct3DSurface9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::SetPrivateData(guid, data, size, flags);
+ }
+
+ long Direct3DSurface9::GetDevice(IDirect3DDevice9 **device)
+ {
+ CriticalSection cs(this->device);
+
+ TRACE("");
+
+ return Direct3DResource9::GetDevice(device);
+ }
+
+ unsigned long Direct3DSurface9::SetPriority(unsigned long newPriority)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::SetPriority(newPriority);
+ }
+
+ unsigned long Direct3DSurface9::GetPriority()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::GetPriority();
+ }
+
+ D3DRESOURCETYPE Direct3DSurface9::GetType()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::GetType();
+ }
+
+ long Direct3DSurface9::GetDC(HDC *deviceContext)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!deviceContext)
+ {
+ return INVALIDCALL();
+ }
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ long Direct3DSurface9::ReleaseDC(HDC deviceContext)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ long Direct3DSurface9::LockRect(D3DLOCKED_RECT *lockedRect, const RECT *rect, unsigned long flags)
+ {
+ CriticalSection cs(device);
+
+ TRACE("D3DLOCKED_RECT *lockedRect = 0x%0.8p, const RECT *rect = 0x%0.8p, unsigned long flags = %d", lockedRect, rect, flags);
+
+ if(!lockedRect)
+ {
+ return INVALIDCALL();
+ }
+
+ lockedRect->Pitch = 0;
+ lockedRect->pBits = 0;
+
+ if(!lockable)
+ {
+ return INVALIDCALL();
+ }
+
+ lockedRect->Pitch = getExternalPitchB();
+
+ sw::Lock lock = sw::LOCK_READWRITE;
+
+ if(flags & D3DLOCK_DISCARD)
+ {
+ lock = sw::LOCK_DISCARD;
+ }
+
+ if(flags & D3DLOCK_READONLY)
+ {
+ lock = sw::LOCK_READONLY;
+ }
+
+ if(rect)
+ {
+ lockedRect->pBits = lockExternal(rect->left, rect->top, 0, lock, sw::PUBLIC);
+ }
+ else
+ {
+ lockedRect->pBits = lockExternal(0, 0, 0, lock, sw::PUBLIC);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DSurface9::UnlockRect()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ unlockExternal();
+
+ return D3D_OK;
+ }
+
+ long Direct3DSurface9::GetContainer(const IID &iid, void **container)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!container)
+ {
+ return INVALIDCALL();
+ }
+
+ long result = this->container->QueryInterface(iid, container);
+
+ if(result == S_OK)
+ {
+ return D3D_OK;
+ }
+
+ return INVALIDCALL();
+ }
+
+ long Direct3DSurface9::GetDesc(D3DSURFACE_DESC *description)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!description)
+ {
+ return INVALIDCALL();
+ }
+
+ description->Format = format;
+ description->Pool = pool;
+ description->Type = D3DRTYPE_SURFACE;
+ description->Height = height;
+ description->Width = width;
+ description->MultiSampleType = multiSample;
+ description->MultiSampleQuality = quality;
+ description->Usage = usage;
+
+ return D3D_OK;
+ }
+
+ sw::Format Direct3DSurface9::translateFormat(D3DFORMAT format)
+ {
+ switch(format)
+ {
+ #if S3TC_SUPPORT
+ case D3DFMT_NULL: return sw::FORMAT_NULL;
+ case D3DFMT_DXT1: return sw::FORMAT_DXT1;
+ case D3DFMT_DXT2: return sw::FORMAT_DXT3;
+ case D3DFMT_DXT3: return sw::FORMAT_DXT3;
+ case D3DFMT_DXT4: return sw::FORMAT_DXT5;
+ case D3DFMT_DXT5: return sw::FORMAT_DXT5;
+ case D3DFMT_ATI1: return sw::FORMAT_ATI1;
+ case D3DFMT_ATI2: return sw::FORMAT_ATI2;
+ #endif
+ case D3DFMT_R3G3B2: return sw::FORMAT_R3G3B2;
+ case D3DFMT_A8R3G3B2: return sw::FORMAT_A8R3G3B2;
+ case D3DFMT_X4R4G4B4: return sw::FORMAT_X4R4G4B4;
+ case D3DFMT_A4R4G4B4: return sw::FORMAT_A4R4G4B4;
+ case D3DFMT_A8R8G8B8: return sw::FORMAT_A8R8G8B8;
+ case D3DFMT_A8B8G8R8: return sw::FORMAT_A8B8G8R8;
+ case D3DFMT_G16R16: return sw::FORMAT_G16R16;
+ case D3DFMT_A2R10G10B10: return sw::FORMAT_A2R10G10B10;
+ case D3DFMT_A2B10G10R10: return sw::FORMAT_A2B10G10R10;
+ case D3DFMT_A16B16G16R16: return sw::FORMAT_A16B16G16R16;
+ case D3DFMT_P8: return sw::FORMAT_P8;
+ case D3DFMT_A8P8: return sw::FORMAT_A8P8;
+ case D3DFMT_A8: return sw::FORMAT_A8;
+ case D3DFMT_R5G6B5: return sw::FORMAT_R5G6B5;
+ case D3DFMT_X1R5G5B5: return sw::FORMAT_X1R5G5B5;
+ case D3DFMT_A1R5G5B5: return sw::FORMAT_A1R5G5B5;
+ case D3DFMT_R8G8B8: return sw::FORMAT_R8G8B8;
+ case D3DFMT_X8R8G8B8: return sw::FORMAT_X8R8G8B8;
+ case D3DFMT_X8B8G8R8: return sw::FORMAT_X8B8G8R8;
+ case D3DFMT_V8U8: return sw::FORMAT_V8U8;
+ case D3DFMT_L6V5U5: return sw::FORMAT_L6V5U5;
+ case D3DFMT_Q8W8V8U8: return sw::FORMAT_Q8W8V8U8;
+ case D3DFMT_X8L8V8U8: return sw::FORMAT_X8L8V8U8;
+ case D3DFMT_A2W10V10U10: return sw::FORMAT_A2W10V10U10;
+ case D3DFMT_V16U16: return sw::FORMAT_V16U16;
+ case D3DFMT_Q16W16V16U16: return sw::FORMAT_Q16W16V16U16;
+ case D3DFMT_L8: return sw::FORMAT_L8;
+ case D3DFMT_A4L4: return sw::FORMAT_A4L4;
+ case D3DFMT_L16: return sw::FORMAT_L16;
+ case D3DFMT_A8L8: return sw::FORMAT_A8L8;
+ case D3DFMT_R16F: return sw::FORMAT_R16F;
+ case D3DFMT_G16R16F: return sw::FORMAT_G16R16F;
+ case D3DFMT_A16B16G16R16F: return sw::FORMAT_A16B16G16R16F;
+ case D3DFMT_R32F: return sw::FORMAT_R32F;
+ case D3DFMT_G32R32F: return sw::FORMAT_G32R32F;
+ case D3DFMT_A32B32G32R32F: return sw::FORMAT_A32B32G32R32F;
+ case D3DFMT_D16: return sw::FORMAT_D16;
+ case D3DFMT_D32: return sw::FORMAT_D32;
+ case D3DFMT_D24X8: return sw::FORMAT_D24X8;
+ case D3DFMT_D24S8: return sw::FORMAT_D24S8;
+ case D3DFMT_D24FS8: return sw::FORMAT_D24FS8;
+ case D3DFMT_D32F_LOCKABLE: return sw::FORMAT_D32F_LOCKABLE;
+ case D3DFMT_DF24: return sw::FORMAT_DF24;
+ case D3DFMT_DF16: return sw::FORMAT_DF16;
+ case D3DFMT_INTZ: return sw::FORMAT_INTZ;
+ default:
+ ASSERT(false);
+ }
+
+ return sw::FORMAT_NULL;
+ }
+
+ int Direct3DSurface9::bytes(D3DFORMAT format)
+ {
+ return Surface::bytes(translateFormat(format));
+ }
+
+ unsigned int Direct3DSurface9::memoryUsage(int width, int height, D3DFORMAT format)
+ {
+ return Surface::size(width, height, 1, translateFormat(format));
+ }
+}
diff --git a/src/D3D9/Direct3DSurface9.hpp b/src/D3D9/Direct3DSurface9.hpp
new file mode 100644
index 0000000..4b9bf87
--- /dev/null
+++ b/src/D3D9/Direct3DSurface9.hpp
@@ -0,0 +1,77 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Direct3DSurface9_hpp
+#define D3D9_Direct3DSurface9_hpp
+
+#include "Direct3DResource9.hpp"
+
+#include "Surface.hpp"
+
+#include <d3d9.h>
+
+namespace D3D9
+{
+ class Direct3DBaseTexture9;
+
+ class Direct3DSurface9 : public IDirect3DSurface9, public Direct3DResource9, public sw::Surface
+ {
+ public:
+ Direct3DSurface9(Direct3DDevice9 *device, Unknown *container, int width, int height, D3DFORMAT format, D3DPOOL pool, D3DMULTISAMPLE_TYPE multiSample, unsigned int quality, bool lockableOverride, unsigned long usage);
+
+ virtual ~Direct3DSurface9();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // IDirect3DResource9 methods
+ long __stdcall FreePrivateData(const GUID &guid);
+ long __stdcall GetPrivateData(const GUID &guid, void *data, unsigned long *size);
+ void __stdcall PreLoad();
+ long __stdcall SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags);
+ long __stdcall GetDevice(IDirect3DDevice9 **device);
+ unsigned long __stdcall SetPriority(unsigned long newPriority);
+ unsigned long __stdcall GetPriority();
+ D3DRESOURCETYPE __stdcall GetType();
+
+ // IDirect3DSurface9 methods
+ long __stdcall GetDC(HDC *deviceContext);
+ long __stdcall ReleaseDC(HDC deviceContext);
+ long __stdcall LockRect(D3DLOCKED_RECT *lockedRect, const RECT *rect, unsigned long Flags);
+ long __stdcall UnlockRect();
+ long __stdcall GetContainer(const IID &iid, void **container);
+ long __stdcall GetDesc(D3DSURFACE_DESC *desc);
+
+ // Internal methods
+ static sw::Format translateFormat(D3DFORMAT format);
+ static int bytes(D3DFORMAT format);
+
+ private:
+ static unsigned int memoryUsage(int width, int height, D3DFORMAT format);
+
+ // Creation parameters
+ Unknown *const container;
+ const int width;
+ const int height;
+ const D3DFORMAT format;
+ const D3DMULTISAMPLE_TYPE multiSample;
+ const unsigned int quality;
+ const D3DPOOL pool;
+ const bool lockable;
+ const unsigned long usage;
+
+ Direct3DBaseTexture9 *parentTexture;
+ };
+}
+
+#endif // D3D9_Direct3DSurface9_hpp
diff --git a/src/D3D9/Direct3DSwapChain9.cpp b/src/D3D9/Direct3DSwapChain9.cpp
new file mode 100644
index 0000000..6efdf6c
--- /dev/null
+++ b/src/D3D9/Direct3DSwapChain9.cpp
@@ -0,0 +1,408 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3DSwapChain9.hpp"
+
+#include "Direct3DDevice9.hpp"
+#include "Renderer.hpp"
+#include "Timer.hpp"
+#include "Resource.hpp"
+#include "Configurator.hpp"
+#include "Debug.hpp"
+
+#include "FrameBufferDD.hpp"
+#include "FrameBufferGDI.hpp"
+
+namespace D3D9
+{
+ Direct3DSwapChain9::Direct3DSwapChain9(Direct3DDevice9 *device, D3DPRESENT_PARAMETERS *presentParameters) : device(device), presentParameters(*presentParameters)
+ {
+ frameBuffer = 0;
+
+ for(int i = 0; i < 3; i++)
+ {
+ backBuffer[i] = 0;
+ }
+
+ reset(presentParameters);
+ }
+
+ Direct3DSwapChain9::~Direct3DSwapChain9()
+ {
+ release();
+ }
+
+ long Direct3DSwapChain9::QueryInterface(const IID &iid, void **object)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(iid == IID_IDirect3DSwapChain9 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long Direct3DSwapChain9::AddRef()
+ {
+ TRACE("");
+
+ return Unknown::AddRef();
+ }
+
+ unsigned long Direct3DSwapChain9::Release()
+ {
+ TRACE("");
+
+ return Unknown::Release();
+ }
+
+ long Direct3DSwapChain9::Present(const RECT *sourceRect, const RECT *destRect, HWND destWindowOverride, const RGNDATA *dirtyRegion, unsigned long flags)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ #if PERF_PROFILE
+ profiler.nextFrame();
+ #endif
+
+ #if PERF_HUD
+ sw::Renderer *renderer = device->renderer;
+
+ static int64_t frame = sw::Timer::ticks();
+
+ int64_t frameTime = sw::Timer::ticks() - frame;
+ frame = sw::Timer::ticks();
+
+ if(frameTime > 0)
+ {
+ unsigned int *frameBuffer = (unsigned int*)lockBackBuffer(0); // FIXME: Don't assume A8R8G8B8 mode
+ unsigned int stride = backBuffer[0]->getInternalPitchP();
+
+ int thread;
+ for(thread = 0; thread < renderer->getThreadCount(); thread++)
+ {
+ int64_t drawTime = renderer->getVertexTime(thread) + renderer->getSetupTime(thread) + renderer->getPixelTime(thread);
+
+ int vertexPercentage = sw::clamp((int)(100 * renderer->getVertexTime(thread) / frameTime), 0, 100);
+ int setupPercentage = sw::clamp((int)(100 * renderer->getSetupTime(thread) / frameTime), 0, 100);
+ int pixelPercentage = sw::clamp((int)(100 * renderer->getPixelTime(thread) / frameTime), 0, 100);
+
+ for(int i = 0; i < 100; i++)
+ {
+ frameBuffer[thread * stride + i] = 0x00000000;
+ }
+
+ unsigned int *buffer = frameBuffer;
+
+ for(int i = 0; i < vertexPercentage; i++)
+ {
+ buffer[thread * stride] = 0x000000FF;
+ buffer++;
+ }
+
+ for(int i = 0; i < setupPercentage; i++)
+ {
+ buffer[thread * stride] = 0x0000FF00;
+ buffer++;
+ }
+
+ for(int i = 0; i < pixelPercentage; i++)
+ {
+ buffer[thread * stride] = 0x00FF0000;
+ buffer++;
+ }
+
+ frameBuffer[thread * stride + 100] = 0x00FFFFFF;
+ }
+
+ for(int i = 0; i <= 100; i++)
+ {
+ frameBuffer[thread * stride + i] = 0x00FFFFFF;
+ }
+
+ unlockBackBuffer(0);
+ }
+
+ renderer->resetTimers();
+ #endif
+
+ HWND window = destWindowOverride ? destWindowOverride : presentParameters.hDeviceWindow;
+ void *source = backBuffer[0]->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC); // FIXME: External
+ bool HDR = backBuffer[0]->getInternalFormat() == sw::FORMAT_A16B16G16R16;
+
+ POINT point;
+ GetCursorPos(&point);
+ ScreenToClient(window, &point);
+
+ frameBuffer->setCursorPosition(point.x, point.y);
+
+ if(!sourceRect && !destRect) // FIXME: More cases?
+ {
+ frameBuffer->flip(window, source, HDR);
+ }
+ else // FIXME: Check for SWAPEFFECT_COPY
+ {
+ sw::Rect sRect = {0};
+ sw::Rect dRect = {0};
+
+ if(sourceRect)
+ {
+ sRect.left = sourceRect->left;
+ sRect.top = sourceRect->top;
+ sRect.right = sourceRect->right;
+ sRect.bottom = sourceRect->bottom;
+ }
+
+ if(destRect)
+ {
+ dRect.left = destRect->left;
+ dRect.top = destRect->top;
+ dRect.right = destRect->right;
+ dRect.bottom = destRect->bottom;
+ }
+
+ frameBuffer->blit(window, source, sourceRect ? &sRect : 0, destRect ? &dRect : 0, HDR);
+ }
+
+ backBuffer[0]->unlockInternal(); // FIXME: External
+
+ return D3D_OK;
+ }
+
+ long Direct3DSwapChain9::GetFrontBufferData(IDirect3DSurface9 *destSurface)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!destSurface)
+ {
+ return INVALIDCALL();
+ }
+
+ sw::Surface *dest = static_cast<Direct3DSurface9*>(destSurface);
+ void *buffer = dest->lockExternal(0, 0, 0, sw::LOCK_WRITEONLY, sw::PRIVATE);
+
+ frameBuffer->screenshot(buffer);
+
+ dest->unlockExternal();
+
+ return D3D_OK;
+ }
+
+ long Direct3DSwapChain9::GetBackBuffer(unsigned int index, D3DBACKBUFFER_TYPE type, IDirect3DSurface9 **backBuffer)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!backBuffer/* || type != D3DBACKBUFFER_TYPE_MONO*/)
+ {
+ return INVALIDCALL();
+ }
+
+ *backBuffer = 0;
+
+ if(index >= 3 || this->backBuffer[index] == 0)
+ {
+ return INVALIDCALL();
+ }
+
+ *backBuffer = this->backBuffer[index];
+ this->backBuffer[index]->AddRef();
+
+ return D3D_OK;
+ }
+
+ long Direct3DSwapChain9::GetRasterStatus(D3DRASTER_STATUS *rasterStatus)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!rasterStatus)
+ {
+ return INVALIDCALL();
+ }
+
+ bool inVerticalBlank;
+ unsigned int scanline;
+ bool supported = frameBuffer->getScanline(inVerticalBlank, scanline);
+
+ if(supported)
+ {
+ rasterStatus->InVBlank = inVerticalBlank;
+ rasterStatus->ScanLine = scanline;
+ }
+ else
+ {
+ return INVALIDCALL();
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DSwapChain9::GetDisplayMode(D3DDISPLAYMODE *displayMode)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!displayMode)
+ {
+ return INVALIDCALL();
+ }
+
+ device->getAdapterDisplayMode(D3DADAPTER_DEFAULT, displayMode);
+
+ return D3D_OK;
+ }
+
+ long Direct3DSwapChain9::GetDevice(IDirect3DDevice9 **device)
+ {
+ CriticalSection cs(this->device);
+
+ TRACE("");
+
+ if(!device)
+ {
+ return INVALIDCALL();
+ }
+
+ this->device->AddRef();
+ *device = this->device;
+
+ return D3D_OK;
+ }
+
+ long Direct3DSwapChain9::GetPresentParameters(D3DPRESENT_PARAMETERS *presentParameters)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!presentParameters)
+ {
+ return INVALIDCALL();
+ }
+
+ *presentParameters = this->presentParameters;
+
+ return D3D_OK;
+ }
+
+ void Direct3DSwapChain9::reset(D3DPRESENT_PARAMETERS *presentParameters)
+ {
+ release();
+
+ ASSERT(presentParameters->BackBufferCount <= 3); // Maximum of three back buffers
+
+ if(presentParameters->BackBufferCount == 0)
+ {
+ presentParameters->BackBufferCount = 1;
+ }
+
+ if(presentParameters->BackBufferFormat == D3DFMT_UNKNOWN)
+ {
+ D3DDISPLAYMODE displayMode;
+ GetDisplayMode(&displayMode);
+
+ presentParameters->BackBufferFormat = displayMode.Format;
+ }
+
+ D3DDEVICE_CREATION_PARAMETERS creationParameters;
+ device->GetCreationParameters(&creationParameters);
+
+ HWND windowHandle = presentParameters->hDeviceWindow ? presentParameters->hDeviceWindow : creationParameters.hFocusWindow;
+
+ if(presentParameters->Windowed && (presentParameters->BackBufferHeight == 0 || presentParameters->BackBufferWidth == 0))
+ {
+ RECT rectangle;
+ GetClientRect(windowHandle, &rectangle);
+
+ presentParameters->BackBufferWidth = rectangle.right - rectangle.left;
+ presentParameters->BackBufferHeight = rectangle.bottom - rectangle.top;
+ }
+
+ lockable = presentParameters->Flags & D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
+
+ sw::Configurator ini("SwiftShader.ini");
+ int api = ini.getInteger("Testing", "FrameBufferAPI", 1);
+
+ if(api == 0)
+ {
+ frameBuffer = new sw::FrameBufferDD(windowHandle, presentParameters->BackBufferWidth, presentParameters->BackBufferHeight, presentParameters->Windowed == FALSE);
+ }
+ else if(api == 1)
+ {
+ frameBuffer = new sw::FrameBufferGDI(windowHandle, presentParameters->BackBufferWidth, presentParameters->BackBufferHeight, presentParameters->Windowed == FALSE);
+ }
+ else ASSERT(false);
+
+ backBuffer[0] = 0;
+ backBuffer[1] = 0;
+ backBuffer[2] = 0;
+
+ for(int i = 0; i < (int)presentParameters->BackBufferCount; i++)
+ {
+ backBuffer[i] = new Direct3DSurface9(device, this, presentParameters->BackBufferWidth, presentParameters->BackBufferHeight, presentParameters->BackBufferFormat, D3DPOOL_DEFAULT, presentParameters->MultiSampleType, presentParameters->MultiSampleQuality, lockable, D3DUSAGE_RENDERTARGET);
+ backBuffer[i]->bind();
+ }
+
+ this->presentParameters = *presentParameters;
+ }
+
+ void Direct3DSwapChain9::release()
+ {
+ delete frameBuffer;
+ frameBuffer = 0;
+
+ for(int i = 0; i < 3; i++)
+ {
+ if(backBuffer[i])
+ {
+ backBuffer[i]->unbind();
+ backBuffer[i] = 0;
+ }
+ }
+ }
+
+ void Direct3DSwapChain9::setGammaRamp(sw::GammaRamp *gammaRamp, bool calibrate)
+ {
+ frameBuffer->setGammaRamp(gammaRamp, calibrate);
+ }
+
+ void Direct3DSwapChain9::getGammaRamp(sw::GammaRamp *gammaRamp)
+ {
+ frameBuffer->getGammaRamp(gammaRamp);
+ }
+
+ void *Direct3DSwapChain9::lockBackBuffer(int index)
+ {
+ return backBuffer[index]->lockInternal(0, 0, 0, sw::LOCK_READWRITE, sw::PUBLIC); // FIXME: External
+ }
+
+ void Direct3DSwapChain9::unlockBackBuffer(int index)
+ {
+ backBuffer[index]->unlockInternal(); // FIXME: External
+ }
+}
diff --git a/src/D3D9/Direct3DSwapChain9.hpp b/src/D3D9/Direct3DSwapChain9.hpp
new file mode 100644
index 0000000..5b6f301
--- /dev/null
+++ b/src/D3D9/Direct3DSwapChain9.hpp
@@ -0,0 +1,73 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Direct3DSwapChain9_hpp
+#define D3D9_Direct3DSwapChain9_hpp
+
+#include "Unknown.hpp"
+
+#include "Direct3DSurface9.hpp"
+
+#include "FrameBuffer.hpp"
+
+#include <d3d9.h>
+
+namespace D3D9
+{
+ class Direct3DDevice9;
+
+ class Direct3DSwapChain9 : public IDirect3DSwapChain9, public Unknown
+ {
+ public:
+ Direct3DSwapChain9(Direct3DDevice9 *device, D3DPRESENT_PARAMETERS *presentParameters);
+
+ virtual ~Direct3DSwapChain9();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // IDirect3DSwapChain9 methods
+ long __stdcall Present(const RECT *sourceRect, const RECT *destRect, HWND destWindowOverride, const RGNDATA *dirtyRegion, unsigned long flags);
+ long __stdcall GetFrontBufferData(IDirect3DSurface9 *destSurface);
+ long __stdcall GetBackBuffer(unsigned int index, D3DBACKBUFFER_TYPE type, IDirect3DSurface9 **backBuffer);
+ long __stdcall GetRasterStatus(D3DRASTER_STATUS *rasterStatus);
+ long __stdcall GetDisplayMode(D3DDISPLAYMODE *displayMode);
+ long __stdcall GetDevice(IDirect3DDevice9 **device);
+ long __stdcall GetPresentParameters(D3DPRESENT_PARAMETERS *presentParameters);
+
+ // Internal methods
+ void reset(D3DPRESENT_PARAMETERS *presentParameters);
+
+ void setGammaRamp(sw::GammaRamp *gammaRamp, bool calibrate);
+ void getGammaRamp(sw::GammaRamp *gammaRamp);
+
+ void *lockBackBuffer(int index);
+ void unlockBackBuffer(int index);
+
+ private:
+ void release();
+
+ // Creation parameters
+ Direct3DDevice9 *const device;
+ D3DPRESENT_PARAMETERS presentParameters;
+
+ bool lockable;
+
+ sw::FrameBuffer *frameBuffer;
+
+ public: // FIXME
+ Direct3DSurface9 *backBuffer[3];
+ };
+}
+
+#endif // D3D9_Direct3DSwapChain9_hpp
diff --git a/src/D3D9/Direct3DTexture9.cpp b/src/D3D9/Direct3DTexture9.cpp
new file mode 100644
index 0000000..5e2f1c3
--- /dev/null
+++ b/src/D3D9/Direct3DTexture9.cpp
@@ -0,0 +1,315 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3DTexture9.hpp"
+
+#include "Direct3DDevice9.hpp"
+#include "Direct3DSurface9.hpp"
+#include "Resource.hpp"
+#include "Debug.hpp"
+
+#include <assert.h>
+
+namespace D3D9
+{
+ Direct3DTexture9::Direct3DTexture9(Direct3DDevice9 *device, unsigned int width, unsigned int height, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool) : Direct3DBaseTexture9(device, D3DRTYPE_TEXTURE, format, pool, levels, usage), width(width), height(height)
+ {
+ if(levels == 0)
+ {
+ this->levels = sw::log2(sw::max((int)width, (int)height, 1)) + 1;
+ }
+
+ for(unsigned int level = 0; level < MIPMAP_LEVELS; level++)
+ {
+ if(level < this->levels)
+ {
+ surfaceLevel[level] = new Direct3DSurface9(device, this, width, height, format, pool, D3DMULTISAMPLE_NONE, 0, false, usage);
+ surfaceLevel[level]->bind();
+ }
+ else
+ {
+ surfaceLevel[level] = 0;
+ }
+
+ width = sw::max(1, (int)width / 2);
+ height = sw::max(1, (int)height / 2);
+ }
+ }
+
+ Direct3DTexture9::~Direct3DTexture9()
+ {
+ resource->lock(sw::DESTRUCT);
+
+ for(int level = 0; level < MIPMAP_LEVELS; level++)
+ {
+ if(surfaceLevel[level])
+ {
+ surfaceLevel[level]->unbind();
+ surfaceLevel[level] = 0;
+ }
+ }
+
+ resource->unlock();
+ }
+
+ long Direct3DTexture9::QueryInterface(const IID &iid, void **object)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(iid == IID_IDirect3DTexture9 ||
+ iid == IID_IDirect3DBaseTexture9 ||
+ iid == IID_IDirect3DResource9 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long Direct3DTexture9::AddRef()
+ {
+ TRACE("");
+
+ return Direct3DBaseTexture9::AddRef();
+ }
+
+ unsigned long Direct3DTexture9::Release()
+ {
+ TRACE("");
+
+ return Direct3DBaseTexture9::Release();
+ }
+
+ long Direct3DTexture9::FreePrivateData(const GUID &guid)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::FreePrivateData(guid);
+ }
+
+ long Direct3DTexture9::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetPrivateData(guid, data, size);
+ }
+
+ void Direct3DTexture9::PreLoad()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ Direct3DBaseTexture9::PreLoad();
+ }
+
+ long Direct3DTexture9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::SetPrivateData(guid, data, size, flags);
+ }
+
+ long Direct3DTexture9::GetDevice(IDirect3DDevice9 **device)
+ {
+ CriticalSection cs(this->device);
+
+ TRACE("IDirect3DDevice9 **device = 0x%0.8p", device);
+
+ return Direct3DBaseTexture9::GetDevice(device);
+ }
+
+ unsigned long Direct3DTexture9::SetPriority(unsigned long newPriority)
+ {
+ CriticalSection cs(device);
+
+ TRACE("unsigned long newPriority = %d", newPriority);
+
+ return Direct3DBaseTexture9::SetPriority(newPriority);
+ }
+
+ unsigned long Direct3DTexture9::GetPriority()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetPriority();
+ }
+
+ D3DRESOURCETYPE Direct3DTexture9::GetType()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetType();
+ }
+
+ void Direct3DTexture9::GenerateMipSubLevels()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!(usage & D3DUSAGE_AUTOGENMIPMAP) || !surfaceLevel[0]->hasDirtyMipmaps())
+ {
+ return;
+ }
+
+ resource->lock(sw::PUBLIC);
+
+ for(unsigned int i = 0; i < levels - 1; i++)
+ {
+ device->stretchRect(surfaceLevel[i], 0, surfaceLevel[i + 1], 0, GetAutoGenFilterType());
+ }
+
+ surfaceLevel[0]->cleanMipmaps();
+
+ resource->unlock();
+ }
+
+ D3DTEXTUREFILTERTYPE Direct3DTexture9::GetAutoGenFilterType()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetAutoGenFilterType();
+ }
+
+ unsigned long Direct3DTexture9::GetLevelCount()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetLevelCount();
+ }
+
+ unsigned long Direct3DTexture9::GetLOD()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetLOD();
+ }
+
+ long Direct3DTexture9::SetAutoGenFilterType(D3DTEXTUREFILTERTYPE filterType)
+ {
+ CriticalSection cs(device);
+
+ TRACE("D3DTEXTUREFILTERTYPE filterType = %d", filterType);
+
+ return Direct3DBaseTexture9::SetAutoGenFilterType(filterType);
+ }
+
+ unsigned long Direct3DTexture9::SetLOD(unsigned long newLOD)
+ {
+ CriticalSection cs(device);
+
+ TRACE("unsigned long newLOD = %d", newLOD);
+
+ return Direct3DBaseTexture9::SetLOD(newLOD);
+ }
+
+ long Direct3DTexture9::GetLevelDesc(unsigned int level, D3DSURFACE_DESC *description)
+ {
+ CriticalSection cs(device);
+
+ TRACE("unsigned int level = %d, D3DSURFACE_DESC *description = 0x%0.8p", level, description);
+
+ if(!description || level >= GetLevelCount() || !surfaceLevel[level])
+ {
+ return INVALIDCALL();
+ }
+
+ return surfaceLevel[level]->GetDesc(description);
+ }
+
+ long Direct3DTexture9::LockRect(unsigned int level, D3DLOCKED_RECT *lockedRect, const RECT *rect, unsigned long flags)
+ {
+ CriticalSection cs(device);
+
+ TRACE("unsigned int level = %d, D3DLOCKED_RECT *lockedRect = 0x%0.8p, const RECT *rect = 0x%0.8p, unsigned long flags = %d", level, lockedRect, rect, flags);
+
+ if(!lockedRect || level >= GetLevelCount() || !surfaceLevel[level])
+ {
+ return INVALIDCALL();
+ }
+
+ return surfaceLevel[level]->LockRect(lockedRect, rect, flags);
+ }
+
+ long Direct3DTexture9::GetSurfaceLevel(unsigned int level, IDirect3DSurface9 **surface)
+ {
+ CriticalSection cs(device);
+
+ TRACE("unsigned int level = %d, IDirect3DSurface9 **surface = 0x%0.8p", level, surface);
+
+ *surface = 0;
+
+ if(level >= GetLevelCount() || !surfaceLevel[level])
+ {
+ return INVALIDCALL();
+ }
+
+ surfaceLevel[level]->AddRef();
+ *surface = surfaceLevel[level];
+
+ return D3D_OK;
+ }
+
+ long Direct3DTexture9::UnlockRect(unsigned int level)
+ {
+ CriticalSection cs(device);
+
+ TRACE("unsigned int level = %d", level);
+
+ if(level >= GetLevelCount() || !surfaceLevel[level])
+ {
+ return INVALIDCALL();
+ }
+
+ return surfaceLevel[level]->UnlockRect();
+ }
+
+ long Direct3DTexture9::AddDirtyRect(const RECT *dirtyRect)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ // UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ Direct3DSurface9 *Direct3DTexture9::getInternalSurfaceLevel(unsigned int level)
+ {
+ return surfaceLevel[level];
+ }
+}
diff --git a/src/D3D9/Direct3DTexture9.hpp b/src/D3D9/Direct3DTexture9.hpp
new file mode 100644
index 0000000..d8ed329
--- /dev/null
+++ b/src/D3D9/Direct3DTexture9.hpp
@@ -0,0 +1,74 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Direct3DTexture9_hpp
+#define D3D9_Direct3DTexture9_hpp
+
+#include "Direct3DBaseTexture9.hpp"
+
+#include "Config.hpp"
+
+#include <d3d9.h>
+
+namespace D3D9
+{
+ class Direct3DSurface9;
+
+ class Direct3DTexture9 : public IDirect3DTexture9, public Direct3DBaseTexture9
+ {
+ public:
+ Direct3DTexture9(Direct3DDevice9 *device, unsigned int width, unsigned int height, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool);
+
+ virtual ~Direct3DTexture9();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // IDirect3DResource9 methods
+ long __stdcall GetDevice(IDirect3DDevice9 **device);
+ long __stdcall SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags);
+ long __stdcall GetPrivateData(const GUID &guid, void *data, unsigned long *size);
+ long __stdcall FreePrivateData(const GUID &guid);
+ unsigned long __stdcall SetPriority(unsigned long newPriority);
+ unsigned long __stdcall GetPriority();
+ void __stdcall PreLoad();
+ D3DRESOURCETYPE __stdcall GetType();
+
+ // IDirect3DBaseTexture9 methods
+ unsigned long __stdcall SetLOD(unsigned long newLOD);
+ unsigned long __stdcall GetLOD();
+ unsigned long __stdcall GetLevelCount();
+ long __stdcall SetAutoGenFilterType(D3DTEXTUREFILTERTYPE filterType);
+ D3DTEXTUREFILTERTYPE __stdcall GetAutoGenFilterType();
+ void __stdcall GenerateMipSubLevels();
+
+ // IDirect3DTexture9 methods
+ long __stdcall GetLevelDesc(unsigned int level, D3DSURFACE_DESC *description);
+ long __stdcall GetSurfaceLevel(unsigned int level, IDirect3DSurface9 **surface);
+ long __stdcall LockRect(unsigned int level, D3DLOCKED_RECT *lockedRect, const RECT *rect, unsigned long flags);
+ long __stdcall UnlockRect(unsigned int level);
+ long __stdcall AddDirtyRect(const RECT *dirtyRect);
+
+ // Internal methods
+ Direct3DSurface9 *getInternalSurfaceLevel(unsigned int level);
+
+ private:
+ // Creation parameters
+ const unsigned int width;
+ const unsigned int height;
+
+ Direct3DSurface9 *surfaceLevel[MIPMAP_LEVELS];
+ };
+}
+
+#endif // D3D9_Direct3DTexture9_hpp
diff --git a/src/D3D9/Direct3DVertexBuffer9.cpp b/src/D3D9/Direct3DVertexBuffer9.cpp
new file mode 100644
index 0000000..55d0931
--- /dev/null
+++ b/src/D3D9/Direct3DVertexBuffer9.cpp
@@ -0,0 +1,264 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3DVertexBuffer9.hpp"
+
+#include "Direct3DDevice9.hpp"
+#include "Resource.hpp"
+#include "Debug.hpp"
+
+#include <assert.h>
+
+namespace D3D9
+{
+ Direct3DVertexBuffer9::Direct3DVertexBuffer9(Direct3DDevice9 *device, unsigned int length, unsigned long usage, long FVF, D3DPOOL pool) : Direct3DResource9(device, D3DRTYPE_VERTEXBUFFER, pool, length), length(length), usage(usage), FVF(FVF)
+ {
+ if(FVF)
+ {
+ unsigned int stride = 0;
+
+ switch(FVF & D3DFVF_POSITION_MASK)
+ {
+ case D3DFVF_XYZ: stride += 12; break;
+ case D3DFVF_XYZRHW: stride += 16; break;
+ case D3DFVF_XYZB1: stride += 16; break;
+ case D3DFVF_XYZB2: stride += 20; break;
+ case D3DFVF_XYZB3: stride += 24; break;
+ case D3DFVF_XYZB4: stride += 28; break;
+ case D3DFVF_XYZB5: stride += 32; break;
+ case D3DFVF_XYZW: stride += 16; break;
+ }
+
+ if(FVF & D3DFVF_NORMAL) stride += 12;
+ if(FVF & D3DFVF_PSIZE) stride += 4;
+ if(FVF & D3DFVF_DIFFUSE) stride += 4;
+ if(FVF & D3DFVF_SPECULAR) stride += 4;
+
+ switch((FVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT)
+ {
+ case 8: stride += 4 + 4 * ((1 + (FVF >> 30)) % 4);
+ case 7: stride += 4 + 4 * ((1 + (FVF >> 28)) % 4);
+ case 6: stride += 4 + 4 * ((1 + (FVF >> 26)) % 4);
+ case 5: stride += 4 + 4 * ((1 + (FVF >> 24)) % 4);
+ case 4: stride += 4 + 4 * ((1 + (FVF >> 22)) % 4);
+ case 3: stride += 4 + 4 * ((1 + (FVF >> 20)) % 4);
+ case 2: stride += 4 + 4 * ((1 + (FVF >> 18)) % 4);
+ case 1: stride += 4 + 4 * ((1 + (FVF >> 16)) % 4);
+ case 0: break;
+ default:
+ ASSERT(false);
+ }
+
+ ASSERT(length >= stride); // FIXME
+ }
+
+ vertexBuffer = new sw::Resource(length + 192 + 1024); // NOTE: Applications can 'overshoot' while writing vertices
+ lockCount = 0;
+ }
+
+ Direct3DVertexBuffer9::~Direct3DVertexBuffer9()
+ {
+ vertexBuffer->destruct();
+ }
+
+ long Direct3DVertexBuffer9::QueryInterface(const IID &iid, void **object)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(iid == IID_IDirect3DVertexBuffer9 ||
+ iid == IID_IDirect3DResource9 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long Direct3DVertexBuffer9::AddRef()
+ {
+ TRACE("");
+
+ return Direct3DResource9::AddRef();
+ }
+
+ unsigned long Direct3DVertexBuffer9::Release()
+ {
+ TRACE("");
+
+ return Direct3DResource9::Release();
+ }
+
+ long Direct3DVertexBuffer9::FreePrivateData(const GUID &guid)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::FreePrivateData(guid);
+ }
+
+ long Direct3DVertexBuffer9::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::GetPrivateData(guid, data, size);
+ }
+
+ void Direct3DVertexBuffer9::PreLoad()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ Direct3DResource9::PreLoad();
+ }
+
+ long Direct3DVertexBuffer9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::SetPrivateData(guid, data, size, flags);
+ }
+
+ long Direct3DVertexBuffer9::GetDevice(IDirect3DDevice9 **device)
+ {
+ CriticalSection cs(this->device);
+
+ TRACE("");
+
+ return Direct3DResource9::GetDevice(device);
+ }
+
+ unsigned long Direct3DVertexBuffer9::SetPriority(unsigned long newPriority)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::SetPriority(newPriority);
+ }
+
+ unsigned long Direct3DVertexBuffer9::GetPriority()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::GetPriority();
+ }
+
+ D3DRESOURCETYPE Direct3DVertexBuffer9::GetType()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DResource9::GetType();
+ }
+
+ long Direct3DVertexBuffer9::Lock(unsigned int offset, unsigned int size, void **data, unsigned long flags)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(offset == 0 && size == 0) // Lock whole buffer
+ {
+ size = length;
+ }
+
+ if(!data || offset + size > length)
+ {
+ return INVALIDCALL();
+ }
+
+ void *buffer;
+
+ if(flags & D3DLOCK_DISCARD/* && usage & D3DUSAGE_DYNAMIC*/)
+ {
+ vertexBuffer->destruct();
+ vertexBuffer = new sw::Resource(length + 192 + 1024); // NOTE: Applications can 'overshoot' while writing vertices
+
+ buffer = (void*)vertexBuffer->getBuffer();
+ }
+ else if(flags & D3DLOCK_NOOVERWRITE/* && usage & D3DUSAGE_DYNAMIC*/)
+ {
+ buffer = (void*)vertexBuffer->getBuffer();
+ }
+ else
+ {
+ buffer = vertexBuffer->lock(sw::PUBLIC);
+ lockCount++;
+ }
+
+ *data = (unsigned char*)buffer + offset;
+
+ return D3D_OK;
+ }
+
+ long Direct3DVertexBuffer9::Unlock()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(lockCount > 0)
+ {
+ vertexBuffer->unlock();
+ lockCount--;
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DVertexBuffer9::GetDesc(D3DVERTEXBUFFER_DESC *description)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!description)
+ {
+ return INVALIDCALL();
+ }
+
+ description->FVF = FVF;
+ description->Format = D3DFMT_VERTEXDATA;
+ description->Pool = pool;
+ description->Size = length;
+ description->Type = D3DRTYPE_VERTEXBUFFER;
+ description->Usage = usage;
+
+ return D3D_OK;
+ }
+
+ int Direct3DVertexBuffer9::getLength() const
+ {
+ return length;
+ }
+
+ sw::Resource *Direct3DVertexBuffer9::getResource() const
+ {
+ return vertexBuffer;
+ }
+}
diff --git a/src/D3D9/Direct3DVertexBuffer9.hpp b/src/D3D9/Direct3DVertexBuffer9.hpp
new file mode 100644
index 0000000..690ee43
--- /dev/null
+++ b/src/D3D9/Direct3DVertexBuffer9.hpp
@@ -0,0 +1,68 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Direct3DVertexBuffer9_hpp
+#define D3D9_Direct3DVertexBuffer9_hpp
+
+#include "Direct3DResource9.hpp"
+
+#include <d3d9.h>
+
+namespace sw
+{
+ class Resource;
+}
+
+namespace D3D9
+{
+ class Direct3DVertexBuffer9 : public IDirect3DVertexBuffer9, public Direct3DResource9
+ {
+ public:
+ Direct3DVertexBuffer9(Direct3DDevice9 *device, unsigned int length, unsigned long usage, long FVF, D3DPOOL pool);
+
+ virtual ~Direct3DVertexBuffer9();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // IDirect3DResource9 methods
+ long __stdcall FreePrivateData(const GUID &guid);
+ long __stdcall GetPrivateData(const GUID &guid, void *data, unsigned long *size);
+ void __stdcall PreLoad();
+ long __stdcall SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags);
+ long __stdcall GetDevice(IDirect3DDevice9 **device);
+ unsigned long __stdcall SetPriority(unsigned long newPriority);
+ unsigned long __stdcall GetPriority();
+ D3DRESOURCETYPE __stdcall GetType();
+
+ // IDirect3DVertexBuffer9 methods
+ long __stdcall Lock(unsigned int offset, unsigned int size, void **data, unsigned long flags);
+ long __stdcall Unlock();
+ long __stdcall GetDesc(D3DVERTEXBUFFER_DESC *description);
+
+ // Internal methods
+ int getLength() const;
+ sw::Resource *getResource() const;
+
+ private:
+ // Creation parameters
+ const unsigned int length;
+ const long usage;
+ const long FVF;
+
+ sw::Resource *vertexBuffer;
+ int lockCount;
+ };
+}
+
+#endif // D3D9_Direct3DVertexBuffer9_hpp
diff --git a/src/D3D9/Direct3DVertexDeclaration9.cpp b/src/D3D9/Direct3DVertexDeclaration9.cpp
new file mode 100644
index 0000000..79b2f56
--- /dev/null
+++ b/src/D3D9/Direct3DVertexDeclaration9.cpp
@@ -0,0 +1,531 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3DVertexDeclaration9.hpp"
+
+#include "Direct3DDevice9.hpp"
+#include "Debug.hpp"
+
+#include <d3d9types.h>
+#include <stdio.h>
+#include <assert.h>
+
+namespace D3D9
+{
+ Direct3DVertexDeclaration9::Direct3DVertexDeclaration9(Direct3DDevice9 *device, const D3DVERTEXELEMENT9 *vertexElement) : device(device)
+ {
+ int size = sizeof(D3DVERTEXELEMENT9);
+ const D3DVERTEXELEMENT9 *element = vertexElement;
+ preTransformed = false;
+
+ while(element->Stream != 0xFF)
+ {
+ if(element->Usage == D3DDECLUSAGE_POSITIONT)
+ {
+ preTransformed = true;
+ }
+
+ size += sizeof(D3DVERTEXELEMENT9);
+ element++;
+ }
+
+ numElements = size / sizeof(D3DVERTEXELEMENT9);
+ this->vertexElement = new D3DVERTEXELEMENT9[numElements];
+ memcpy(this->vertexElement, vertexElement, size);
+
+ FVF = computeFVF();
+ }
+
+ Direct3DVertexDeclaration9::Direct3DVertexDeclaration9(Direct3DDevice9 *device, unsigned long FVF) : device(device)
+ {
+ this->FVF = FVF;
+
+ vertexElement = new D3DVERTEXELEMENT9[16];
+
+ numElements = 0;
+ int offset = 0;
+ preTransformed = false;
+
+ switch(FVF & D3DFVF_POSITION_MASK)
+ {
+ case 0:
+ // No position stream
+ break;
+ case D3DFVF_XYZ:
+ vertexElement[numElements].Stream = 0;
+ vertexElement[numElements].Offset = offset;
+ vertexElement[numElements].Type = D3DDECLTYPE_FLOAT3;
+ vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
+ vertexElement[numElements].Usage = D3DDECLUSAGE_POSITION;
+ vertexElement[numElements].UsageIndex = 0;
+ numElements++;
+ offset += 4 * 3;
+ break;
+ case D3DFVF_XYZRHW:
+ preTransformed = true;
+ vertexElement[numElements].Stream = 0;
+ vertexElement[numElements].Offset = offset;
+ vertexElement[numElements].Type = D3DDECLTYPE_FLOAT4;
+ vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
+ vertexElement[numElements].Usage = D3DDECLUSAGE_POSITIONT;
+ vertexElement[numElements].UsageIndex = 0;
+ numElements++;
+ offset += 4 * 4;
+ break;
+ case D3DFVF_XYZB1:
+ vertexElement[numElements].Stream = 0;
+ vertexElement[numElements].Offset = offset;
+ vertexElement[numElements].Type = D3DDECLTYPE_FLOAT3;
+ vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
+ vertexElement[numElements].Usage = D3DDECLUSAGE_POSITION;
+ vertexElement[numElements].UsageIndex = 0;
+ numElements++;
+ offset += 4 * 3;
+
+ vertexElement[numElements].Stream = 0;
+ vertexElement[numElements].Offset = offset;
+ vertexElement[numElements].Type = D3DDECLTYPE_FLOAT1;
+ vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
+ vertexElement[numElements].Usage = D3DDECLUSAGE_BLENDWEIGHT;
+ vertexElement[numElements].UsageIndex = 0;
+ numElements++;
+ offset += 4 * 1;
+ break;
+ case D3DFVF_XYZB2:
+ vertexElement[numElements].Stream = 0;
+ vertexElement[numElements].Offset = offset;
+ vertexElement[numElements].Type = D3DDECLTYPE_FLOAT3;
+ vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
+ vertexElement[numElements].Usage = D3DDECLUSAGE_POSITION;
+ vertexElement[numElements].UsageIndex = 0;
+ numElements++;
+ offset += 4 * 3;
+
+ vertexElement[numElements].Stream = 0;
+ vertexElement[numElements].Offset = offset;
+ vertexElement[numElements].Type = D3DDECLTYPE_FLOAT2;
+ vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
+ vertexElement[numElements].Usage = D3DDECLUSAGE_BLENDWEIGHT;
+ vertexElement[numElements].UsageIndex = 0;
+ numElements++;
+ offset += 4 * 2;
+ break;
+ case D3DFVF_XYZB3:
+ vertexElement[numElements].Stream = 0;
+ vertexElement[numElements].Offset = offset;
+ vertexElement[numElements].Type = D3DDECLTYPE_FLOAT3;
+ vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
+ vertexElement[numElements].Usage = D3DDECLUSAGE_POSITION;
+ vertexElement[numElements].UsageIndex = 0;
+ numElements++;
+ offset += 4 * 3;
+
+ vertexElement[numElements].Stream = 0;
+ vertexElement[numElements].Offset = offset;
+ vertexElement[numElements].Type = D3DDECLTYPE_FLOAT3;
+ vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
+ vertexElement[numElements].Usage = D3DDECLUSAGE_BLENDWEIGHT;
+ vertexElement[numElements].UsageIndex = 0;
+ numElements++;
+ offset += 4 * 3;
+ break;
+ case D3DFVF_XYZB4:
+ vertexElement[numElements].Stream = 0;
+ vertexElement[numElements].Offset = offset;
+ vertexElement[numElements].Type = D3DDECLTYPE_FLOAT3;
+ vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
+ vertexElement[numElements].Usage = D3DDECLUSAGE_POSITION;
+ vertexElement[numElements].UsageIndex = 0;
+ numElements++;
+ offset += 4 * 3;
+
+ vertexElement[numElements].Stream = 0;
+ vertexElement[numElements].Offset = offset;
+ vertexElement[numElements].Type = D3DDECLTYPE_FLOAT4;
+ vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
+ vertexElement[numElements].Usage = D3DDECLUSAGE_BLENDWEIGHT;
+ vertexElement[numElements].UsageIndex = 0;
+ numElements++;
+ offset += 4 * 4;
+ break;
+ case D3DFVF_XYZB5:
+ vertexElement[numElements].Stream = 0;
+ vertexElement[numElements].Offset = offset;
+ vertexElement[numElements].Type = D3DDECLTYPE_FLOAT3;
+ vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
+ vertexElement[numElements].Usage = D3DDECLUSAGE_POSITION;
+ vertexElement[numElements].UsageIndex = 0;
+ numElements++;
+ offset += 4 * 3;
+
+ vertexElement[numElements].Stream = 0;
+ vertexElement[numElements].Offset = offset;
+ vertexElement[numElements].Type = D3DDECLTYPE_FLOAT4;
+ vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
+ vertexElement[numElements].Usage = D3DDECLUSAGE_BLENDWEIGHT;
+ vertexElement[numElements].UsageIndex = 0;
+ numElements++;
+ offset += 4 * 5;
+ break;
+ case D3DFVF_XYZW:
+ vertexElement[numElements].Stream = 0;
+ vertexElement[numElements].Offset = offset;
+ vertexElement[numElements].Type = D3DDECLTYPE_FLOAT4;
+ vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
+ vertexElement[numElements].Usage = D3DDECLUSAGE_POSITION;
+ vertexElement[numElements].UsageIndex = 0;
+ numElements++;
+ offset += 4 * 4;
+ break;
+ default:
+ ASSERT(false);
+ }
+
+ if(FVF & D3DFVF_NORMAL)
+ {
+ vertexElement[numElements].Stream = 0;
+ vertexElement[numElements].Offset = offset;
+ vertexElement[numElements].Type = D3DDECLTYPE_FLOAT3;
+ vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
+ vertexElement[numElements].Usage = D3DDECLUSAGE_NORMAL;
+ vertexElement[numElements].UsageIndex = 0;
+ numElements++;
+ offset += 4 * 3;
+ }
+
+ if(FVF & D3DFVF_PSIZE)
+ {
+ vertexElement[numElements].Stream = 0;
+ vertexElement[numElements].Offset = offset;
+ vertexElement[numElements].Type = D3DDECLTYPE_FLOAT1;
+ vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
+ vertexElement[numElements].Usage = D3DDECLUSAGE_PSIZE;
+ vertexElement[numElements].UsageIndex = 0;
+ numElements++;
+ offset += 4;
+ }
+
+ if(FVF & D3DFVF_DIFFUSE)
+ {
+ vertexElement[numElements].Stream = 0;
+ vertexElement[numElements].Offset = offset;
+ vertexElement[numElements].Type = D3DDECLTYPE_D3DCOLOR;
+ vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
+ vertexElement[numElements].Usage = D3DDECLUSAGE_COLOR;
+ vertexElement[numElements].UsageIndex = 0;
+ numElements++;
+ offset += 4;
+ }
+
+ if(FVF & D3DFVF_SPECULAR)
+ {
+ vertexElement[numElements].Stream = 0;
+ vertexElement[numElements].Offset = offset;
+ vertexElement[numElements].Type = D3DDECLTYPE_D3DCOLOR;
+ vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
+ vertexElement[numElements].Usage = D3DDECLUSAGE_COLOR;
+ vertexElement[numElements].UsageIndex = 1;
+ numElements++;
+ offset += 4;
+ }
+
+ int numTexCoord = (FVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
+ int textureFormats = (FVF >> 16) & 0xFFFF;
+
+ static const int textureSize[4] =
+ {
+ 2 * 4, // D3DFVF_TEXTUREFORMAT2
+ 3 * 4, // D3DFVF_TEXTUREFORMAT3
+ 4 * 4, // D3DFVF_TEXTUREFORMAT4
+ 1 * 4 // D3DFVF_TEXTUREFORMAT1
+ };
+
+ static const D3DDECLTYPE textureType[4] =
+ {
+ D3DDECLTYPE_FLOAT2, // D3DFVF_TEXTUREFORMAT2
+ D3DDECLTYPE_FLOAT3, // D3DFVF_TEXTUREFORMAT3
+ D3DDECLTYPE_FLOAT4, // D3DFVF_TEXTUREFORMAT4
+ D3DDECLTYPE_FLOAT1 // D3DFVF_TEXTUREFORMAT1
+ };
+
+ for(int i = 0; i < numTexCoord; i++)
+ {
+ vertexElement[numElements].Stream = 0;
+ vertexElement[numElements].Offset = offset;
+ vertexElement[numElements].Type = textureType[textureFormats & 0x3];
+ vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
+ vertexElement[numElements].Usage = D3DDECLUSAGE_TEXCOORD;
+ vertexElement[numElements].UsageIndex = i;
+ numElements++;
+ offset += textureSize[textureFormats & 0x3];
+ textureFormats >>= 2;
+ }
+
+ // D3DDECL_END()
+ vertexElement[numElements].Stream = 0xFF;
+ vertexElement[numElements].Offset = 0;
+ vertexElement[numElements].Type = D3DDECLTYPE_UNUSED;
+ vertexElement[numElements].Method = 0;
+ vertexElement[numElements].Usage = 0;
+ vertexElement[numElements].UsageIndex = 0;
+ numElements++;
+ }
+
+ Direct3DVertexDeclaration9::~Direct3DVertexDeclaration9()
+ {
+ delete[] vertexElement;
+ vertexElement = 0;
+ }
+
+ long Direct3DVertexDeclaration9::QueryInterface(const IID &iid, void **object)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(iid == IID_IDirect3DVertexDeclaration9 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long Direct3DVertexDeclaration9::AddRef()
+ {
+ TRACE("");
+
+ return Unknown::AddRef();
+ }
+
+ unsigned long Direct3DVertexDeclaration9::Release()
+ {
+ TRACE("");
+
+ return Unknown::Release();
+ }
+
+ long Direct3DVertexDeclaration9::GetDevice(IDirect3DDevice9 **device)
+ {
+ CriticalSection cs(this->device);
+
+ TRACE("");
+
+ if(!device)
+ {
+ return INVALIDCALL();
+ }
+
+ this->device->AddRef();
+ *device = this->device;
+
+ return D3D_OK;
+ }
+
+ long Direct3DVertexDeclaration9::GetDeclaration(D3DVERTEXELEMENT9 *declaration, unsigned int *numElements)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!declaration || !numElements)
+ {
+ return INVALIDCALL();
+ }
+
+ *numElements = this->numElements;
+
+ for(int i = 0; i < this->numElements; i++)
+ {
+ declaration[i] = vertexElement[i];
+ }
+
+ return D3D_OK;
+ }
+
+ unsigned long Direct3DVertexDeclaration9::getFVF() const
+ {
+ return FVF;
+ }
+
+ bool Direct3DVertexDeclaration9::isPreTransformed() const
+ {
+ return preTransformed;
+ }
+
+ unsigned long Direct3DVertexDeclaration9::computeFVF()
+ {
+ unsigned long FVF = 0;
+
+ int textureBits = 0;
+ int numBlendWeights = 0;
+
+ for(int i = 0; i < numElements - 1; i++)
+ {
+ D3DVERTEXELEMENT9 &element = vertexElement[i];
+
+ if(element.Stream != 0)
+ {
+ return 0;
+ }
+
+ switch(element.Usage)
+ {
+ case D3DDECLUSAGE_POSITION:
+ if(element.Type == D3DDECLTYPE_FLOAT3 && element.UsageIndex == 0)
+ {
+ FVF |= D3DFVF_XYZ;
+ }
+ else
+ {
+ return 0;
+ }
+ break;
+ case D3DDECLUSAGE_POSITIONT:
+ if(element.Type == D3DDECLTYPE_FLOAT4 && element.UsageIndex == 0)
+ {
+ FVF |= D3DFVF_XYZRHW;
+ }
+ else
+ {
+ return 0;
+ }
+ break;
+ case D3DDECLUSAGE_BLENDWEIGHT:
+ if(element.Type <= D3DDECLTYPE_FLOAT4 && element.UsageIndex == 0)
+ {
+ numBlendWeights += element.Type + 1;
+ }
+ else
+ {
+ return 0;
+ }
+ break;
+ case D3DDECLUSAGE_BLENDINDICES:
+ return 0;
+ break;
+ case D3DDECLUSAGE_NORMAL:
+ if(element.Type == D3DDECLTYPE_FLOAT3 && element.UsageIndex == 0)
+ {
+ FVF |= D3DFVF_NORMAL;
+ }
+ else
+ {
+ return 0;
+ }
+ break;
+ case D3DDECLUSAGE_PSIZE:
+ if(element.Type == D3DDECLTYPE_FLOAT1 && element.UsageIndex == 0)
+ {
+ FVF |= D3DFVF_PSIZE;
+ }
+ else
+ {
+ return 0;
+ }
+ break;
+ case D3DDECLUSAGE_COLOR:
+ if(element.Type == D3DDECLTYPE_D3DCOLOR && element.UsageIndex < 2)
+ {
+ if(element.UsageIndex == 0)
+ {
+ FVF |= D3DFVF_DIFFUSE;
+ }
+ else // element.UsageIndex == 1
+ {
+ FVF |= D3DFVF_SPECULAR;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+ break;
+ case D3DDECLUSAGE_TEXCOORD:
+ if((element.Type > D3DDECLTYPE_FLOAT4) || (element.UsageIndex > 7))
+ {
+ return 0;
+ }
+
+ int bit = 1 << element.UsageIndex;
+
+ if(textureBits & bit)
+ {
+ return 0;
+ }
+
+ textureBits |= bit;
+
+ switch(element.Type)
+ {
+ case D3DDECLTYPE_FLOAT1:
+ FVF |= D3DFVF_TEXCOORDSIZE1(element.UsageIndex);
+ break;
+ case D3DDECLTYPE_FLOAT2:
+ FVF |= D3DFVF_TEXCOORDSIZE2(element.UsageIndex);
+ break;
+ case D3DDECLTYPE_FLOAT3:
+ FVF |= D3DFVF_TEXCOORDSIZE3(element.UsageIndex);
+ break;
+ case D3DDECLTYPE_FLOAT4:
+ FVF |= D3DFVF_TEXCOORDSIZE4(element.UsageIndex);
+ break;
+ }
+ }
+ }
+
+ bool isTransformed = (FVF & D3DFVF_XYZRHW) != 0;
+
+ if(isTransformed)
+ {
+ if(numBlendWeights != 0)
+ {
+ return 0;
+ }
+ }
+ else if((FVF & D3DFVF_XYZ) == 0)
+ {
+ return 0;
+ }
+
+ int positionMask = isTransformed ? 0x2 : 0x1;
+
+ if(numBlendWeights)
+ {
+ positionMask += numBlendWeights + 1;
+ }
+
+ int numTexCoord = 0;
+
+ while(textureBits & 1)
+ {
+ textureBits >>= 1;
+
+ numTexCoord++;
+ }
+
+ if(textureBits) // FVF does not allow
+ {
+ return 0;
+ }
+
+ FVF |= D3DFVF_POSITION_MASK & (positionMask << 1);
+ FVF |= numTexCoord << D3DFVF_TEXCOUNT_SHIFT;
+
+ return FVF;
+ }
+}
diff --git a/src/D3D9/Direct3DVertexDeclaration9.hpp b/src/D3D9/Direct3DVertexDeclaration9.hpp
new file mode 100644
index 0000000..8c40d09
--- /dev/null
+++ b/src/D3D9/Direct3DVertexDeclaration9.hpp
@@ -0,0 +1,57 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Direct3DVertexDeclaration9_hpp
+#define D3D9_Direct3DVertexDeclaration9_hpp
+
+#include "Unknown.hpp"
+
+#include <d3d9.h>
+
+namespace D3D9
+{
+ class Direct3DDevice9;
+
+ class Direct3DVertexDeclaration9 : public IDirect3DVertexDeclaration9, public Unknown
+ {
+ public:
+ Direct3DVertexDeclaration9(Direct3DDevice9 *device, const D3DVERTEXELEMENT9 *vertexElements);
+ Direct3DVertexDeclaration9(Direct3DDevice9 *device, unsigned long FVF);
+
+ virtual ~Direct3DVertexDeclaration9();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // IDirect3DVertexDeclaration9 methods
+ long __stdcall GetDevice(IDirect3DDevice9 **device);
+ long __stdcall GetDeclaration(D3DVERTEXELEMENT9 *declaration, unsigned int *numElements);
+
+ // Internal methods
+ unsigned long getFVF() const;
+ bool isPreTransformed() const;
+
+ private:
+ unsigned long computeFVF(); // If equivalent to FVF, else 0
+
+ // Creation parameters
+ Direct3DDevice9 *const device;
+ D3DVERTEXELEMENT9 *vertexElement;
+
+ int numElements;
+ unsigned long FVF;
+ bool preTransformed;
+ };
+}
+
+#endif // D3D9_Direct3DVertexDeclaration9_hpp
diff --git a/src/D3D9/Direct3DVertexShader9.cpp b/src/D3D9/Direct3DVertexShader9.cpp
new file mode 100644
index 0000000..00af8da
--- /dev/null
+++ b/src/D3D9/Direct3DVertexShader9.cpp
@@ -0,0 +1,98 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3DVertexShader9.hpp"
+
+#include "Direct3DDevice9.hpp"
+#include "Debug.hpp"
+
+namespace D3D9
+{
+ Direct3DVertexShader9::Direct3DVertexShader9(Direct3DDevice9 *device, const unsigned long *shaderToken) : device(device), vertexShader(shaderToken)
+ {
+ }
+
+ Direct3DVertexShader9::~Direct3DVertexShader9()
+ {
+ }
+
+ long Direct3DVertexShader9::QueryInterface(const IID &iid, void **object)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(iid == IID_IDirect3DVertexShader9 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long Direct3DVertexShader9::AddRef()
+ {
+ TRACE("");
+
+ return Unknown::AddRef();
+ }
+
+ unsigned long Direct3DVertexShader9::Release()
+ {
+ TRACE("");
+
+ return Unknown::Release();
+ }
+
+ long Direct3DVertexShader9::GetDevice(IDirect3DDevice9 **device)
+ {
+ CriticalSection cs(this->device);
+
+ TRACE("");
+
+ if(!device)
+ {
+ return INVALIDCALL();
+ }
+
+ this->device->AddRef();
+ *device = this->device;
+
+ return D3D_OK;
+ }
+
+ long Direct3DVertexShader9::GetFunction(void *data, unsigned int *size)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!size)
+ {
+ return INVALIDCALL();
+ }
+
+ vertexShader.getFunction(data, size);
+
+ return D3D_OK;
+ }
+
+ const sw::VertexShader *Direct3DVertexShader9::getVertexShader() const
+ {
+ return &vertexShader;
+ }
+}
diff --git a/src/D3D9/Direct3DVertexShader9.hpp b/src/D3D9/Direct3DVertexShader9.hpp
new file mode 100644
index 0000000..da317a4
--- /dev/null
+++ b/src/D3D9/Direct3DVertexShader9.hpp
@@ -0,0 +1,52 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Direct3DVertexShader9_hpp
+#define D3D9_Direct3DVertexShader9_hpp
+
+#include "Unknown.hpp"
+
+#include "VertexShader.hpp"
+
+#include <d3d9.h>
+
+namespace D3D9
+{
+ class Direct3DDevice9;
+
+ class Direct3DVertexShader9 : public IDirect3DVertexShader9, public Unknown
+ {
+ public:
+ Direct3DVertexShader9(Direct3DDevice9 *device, const unsigned long *shaderToken);
+
+ virtual ~Direct3DVertexShader9();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // IDirect3DVertexShader9 methods
+ long __stdcall GetDevice(IDirect3DDevice9 **device);
+ long __stdcall GetFunction(void *data, unsigned int *size);
+
+ // Internal methods
+ const sw::VertexShader *getVertexShader() const;
+
+ private:
+ // Creation parameters
+ Direct3DDevice9 *const device;
+
+ sw::VertexShader vertexShader;
+ };
+}
+
+#endif // D3D9_Direct3DVertexShader9_hpp
diff --git a/src/D3D9/Direct3DVolume9.cpp b/src/D3D9/Direct3DVolume9.cpp
new file mode 100644
index 0000000..e45ff09
--- /dev/null
+++ b/src/D3D9/Direct3DVolume9.cpp
@@ -0,0 +1,221 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3DVolume9.hpp"
+
+#include "Direct3DDevice9.hpp"
+#include "Direct3DResource9.hpp"
+#include "Direct3DVolumeTexture9.hpp"
+#include "Direct3DSurface9.hpp"
+#include "Resource.hpp"
+#include "Debug.hpp"
+
+#include <assert.h>
+
+namespace D3D9
+{
+ bool isLockable(D3DPOOL pool, unsigned long usage)
+ {
+ return (pool != D3DPOOL_DEFAULT) || (usage & D3DUSAGE_DYNAMIC);
+ }
+
+ Direct3DVolume9::Direct3DVolume9(Direct3DDevice9 *device, Direct3DVolumeTexture9 *container, int width, int height, int depth, D3DFORMAT format, D3DPOOL pool, unsigned long usage) : device(device), Surface(container->getResource(), width, height, depth, translateFormat(format), isLockable(pool, usage), false), container(container), width(width), height(height), depth(depth), format(format), pool(pool), lockable(isLockable(pool, usage)), usage(usage)
+ {
+ resource = new Direct3DResource9(device, D3DRTYPE_VOLUME, pool, memoryUsage(width, height, depth, format));
+ resource->bind();
+ }
+
+ Direct3DVolume9::~Direct3DVolume9()
+ {
+ resource->unbind();
+ }
+
+ long __stdcall Direct3DVolume9::QueryInterface(const IID &iid, void **object)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(iid == IID_IDirect3DVolume9 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long __stdcall Direct3DVolume9::AddRef()
+ {
+ TRACE("");
+
+ return container->AddRef();
+ }
+
+ unsigned long __stdcall Direct3DVolume9::Release()
+ {
+ TRACE("");
+
+ return container->Release();
+ }
+
+ long Direct3DVolume9::FreePrivateData(const GUID &guid)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return resource->FreePrivateData(guid);
+ }
+
+ long Direct3DVolume9::GetContainer(const IID &iid, void **container)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!container)
+ {
+ return INVALIDCALL();
+ }
+
+ long result = this->container->QueryInterface(iid, container);
+
+ if(result == S_OK)
+ {
+ return D3D_OK;
+ }
+
+ return INVALIDCALL();
+ }
+
+ long Direct3DVolume9::GetDesc(D3DVOLUME_DESC *description)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!description)
+ {
+ return INVALIDCALL();
+ }
+
+ description->Format = format;
+ description->Type = D3DRTYPE_VOLUME;
+ description->Usage = usage;
+ description->Pool = pool;
+ description->Width = width;
+ description->Height = height;
+ description->Depth = depth;
+
+ return D3D_OK;
+ }
+
+ long Direct3DVolume9::GetDevice(IDirect3DDevice9 **device)
+ {
+ CriticalSection cs(this->device);
+
+ TRACE("");
+
+ return resource->GetDevice(device);
+ }
+
+ long Direct3DVolume9::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return resource->GetPrivateData(guid, data, size);
+ }
+
+ long Direct3DVolume9::LockBox(D3DLOCKED_BOX *lockedVolume, const D3DBOX *box, unsigned long flags)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!lockedVolume)
+ {
+ return INVALIDCALL();
+ }
+
+ lockedVolume->RowPitch = 0;
+ lockedVolume->SlicePitch = 0;
+ lockedVolume->pBits = 0;
+
+ if(!lockable)
+ {
+ return INVALIDCALL();
+ }
+
+ lockedVolume->RowPitch = getExternalPitchB();
+ lockedVolume->SlicePitch = getExternalSliceB();
+
+ sw::Lock lock = sw::LOCK_READWRITE;
+
+ if(flags & D3DLOCK_DISCARD)
+ {
+ lock = sw::LOCK_DISCARD;
+ }
+
+ if(flags & D3DLOCK_READONLY)
+ {
+ lock = sw::LOCK_READONLY;
+ }
+
+ if(box)
+ {
+ lockedVolume->pBits = lockExternal(box->Left, box->Top, box->Front, lock, sw::PUBLIC);
+ }
+ else
+ {
+ lockedVolume->pBits = lockExternal(0, 0, 0, lock, sw::PUBLIC);
+ }
+
+ return D3D_OK;
+ }
+
+ long Direct3DVolume9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return resource->SetPrivateData(guid, data, size, flags);
+ }
+
+ long Direct3DVolume9::UnlockBox()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ unlockExternal();
+
+ return D3D_OK;
+ }
+
+ sw::Format Direct3DVolume9::translateFormat(D3DFORMAT format)
+ {
+ return Direct3DSurface9::translateFormat(format);
+ }
+
+ unsigned int Direct3DVolume9::memoryUsage(int width, int height, int depth, D3DFORMAT format)
+ {
+ return Surface::size(width, height, depth, translateFormat(format));
+ }
+}
diff --git a/src/D3D9/Direct3DVolume9.hpp b/src/D3D9/Direct3DVolume9.hpp
new file mode 100644
index 0000000..004c3da
--- /dev/null
+++ b/src/D3D9/Direct3DVolume9.hpp
@@ -0,0 +1,68 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Direct3DVolume9_hpp
+#define D3D9_Direct3DVolume9_hpp
+
+#include "Unknown.hpp"
+
+#include "Surface.hpp"
+
+#include <d3d9.h>
+
+namespace D3D9
+{
+ class Direct3DDevice9;
+ class Direct3DResource9;
+ class Direct3DVolumeTexture9;
+
+ class Direct3DVolume9 : public IDirect3DVolume9, public Unknown, public sw::Surface
+ {
+ public:
+ Direct3DVolume9(Direct3DDevice9 *device, Direct3DVolumeTexture9 *container, int width, int height, int depth, D3DFORMAT format, D3DPOOL pool, unsigned long usage);
+
+ virtual ~Direct3DVolume9();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // IDirect3DVolume9 methods
+ long __stdcall FreePrivateData(const GUID &guid);
+ long __stdcall GetContainer(const IID &iid, void **container);
+ long __stdcall GetDesc(D3DVOLUME_DESC *description);
+ long __stdcall GetDevice(IDirect3DDevice9 **device);
+ long __stdcall GetPrivateData(const GUID &guid, void *data, unsigned long *size);
+ long __stdcall LockBox(D3DLOCKED_BOX *lockedVolume, const D3DBOX *box, unsigned long flags);
+ long __stdcall SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags);
+ long __stdcall UnlockBox();
+
+ private:
+ static sw::Format translateFormat(D3DFORMAT format);
+ static unsigned int memoryUsage(int width, int height, int depth, D3DFORMAT format);
+
+ // Creation parameters
+ Direct3DDevice9 *const device;
+ Direct3DVolumeTexture9 *const container;
+ const int width;
+ const int height;
+ const int depth;
+ const D3DFORMAT format;
+ const D3DPOOL pool;
+ const bool lockable;
+ const unsigned long usage;
+
+ Direct3DResource9 *resource;
+ };
+}
+
+#endif // D3D9_Direct3DVolume9_hpp
diff --git a/src/D3D9/Direct3DVolumeTexture9.cpp b/src/D3D9/Direct3DVolumeTexture9.cpp
new file mode 100644
index 0000000..95ce903
--- /dev/null
+++ b/src/D3D9/Direct3DVolumeTexture9.cpp
@@ -0,0 +1,371 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Direct3DVolumeTexture9.hpp"
+
+#include "Direct3DVolume9.hpp"
+#include "Direct3DDevice9.hpp"
+#include "Resource.hpp"
+#include "Debug.hpp"
+
+#include <assert.h>
+
+namespace D3D9
+{
+ Direct3DVolumeTexture9::Direct3DVolumeTexture9(Direct3DDevice9 *device, unsigned int width, unsigned int height, unsigned int depth, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool) : Direct3DBaseTexture9(device, D3DRTYPE_VOLUMETEXTURE, format, pool, levels, usage), width(width), height(height), depth(depth)
+ {
+ if(levels == 0)
+ {
+ this->levels = sw::log2(sw::max((int)width, (int)height, (int)depth, 1)) + 1;
+ }
+
+ for(unsigned int level = 0; level < MIPMAP_LEVELS; level++)
+ {
+ if(level < this->levels)
+ {
+ volumeLevel[level] = new Direct3DVolume9(device, this, width, height, depth, format, pool, usage);
+ volumeLevel[level]->bind();
+ }
+ else
+ {
+ volumeLevel[level] = 0;
+ }
+
+ width = sw::max(1, (int)width / 2);
+ height = sw::max(1, (int)height / 2);
+ depth = sw::max(1, (int)depth / 2);
+ }
+ }
+
+ Direct3DVolumeTexture9::~Direct3DVolumeTexture9()
+ {
+ resource->lock(sw::DESTRUCT);
+
+ for(int level = 0; level < MIPMAP_LEVELS; level++)
+ {
+ if(volumeLevel[level])
+ {
+ volumeLevel[level]->unbind();
+ volumeLevel[level] = 0;
+ }
+ }
+
+ resource->unlock();
+ }
+
+ long Direct3DVolumeTexture9::QueryInterface(const IID &iid, void **object)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(iid == IID_IDirect3DVolumeTexture9 ||
+ iid == IID_IDirect3DBaseTexture9 ||
+ iid == IID_IDirect3DResource9 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long Direct3DVolumeTexture9::AddRef()
+ {
+ TRACE("");
+
+ return Direct3DBaseTexture9::AddRef();
+ }
+
+ unsigned long Direct3DVolumeTexture9::Release()
+ {
+ TRACE("");
+
+ return Direct3DBaseTexture9::Release();
+ }
+
+ long Direct3DVolumeTexture9::FreePrivateData(const GUID &guid)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::FreePrivateData(guid);
+ }
+
+ long Direct3DVolumeTexture9::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetPrivateData(guid, data, size);
+ }
+
+ void Direct3DVolumeTexture9::PreLoad()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ Direct3DBaseTexture9::PreLoad();
+ }
+
+ long Direct3DVolumeTexture9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::SetPrivateData(guid, data, size, flags);
+ }
+
+ long Direct3DVolumeTexture9::GetDevice(IDirect3DDevice9 **device)
+ {
+ CriticalSection(this->device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetDevice(device);
+ }
+
+ unsigned long Direct3DVolumeTexture9::SetPriority(unsigned long newPriority)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::SetPriority(newPriority);
+ }
+
+ unsigned long Direct3DVolumeTexture9::GetPriority()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetPriority();
+ }
+
+ D3DRESOURCETYPE Direct3DVolumeTexture9::GetType()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetType();
+ }
+
+ void Direct3DVolumeTexture9::GenerateMipSubLevels()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!(usage & D3DUSAGE_AUTOGENMIPMAP) || !volumeLevel[0]->hasDirtyMipmaps())
+ {
+ return;
+ }
+
+ resource->lock(sw::PUBLIC);
+
+ for(unsigned int i = 0; i < levels - 1; i++)
+ {
+ Direct3DVolume9 *source = volumeLevel[i];
+ Direct3DVolume9 *dest = volumeLevel[i + 1];
+
+ source->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
+ dest->lockInternal(0, 0, 0, sw::LOCK_DISCARD, sw::PUBLIC);
+
+ int sWidth = source->getInternalWidth();
+ int sHeight = source->getInternalHeight();
+ int sDepth = source->getInternalDepth();
+
+ int dWidth = dest->getInternalWidth();
+ int dHeight = dest->getInternalHeight();
+ int dDepth = dest->getInternalDepth();
+
+ D3DTEXTUREFILTERTYPE filter = GetAutoGenFilterType();
+
+ float w = (float)sWidth / (float)dWidth;
+ float h = (float)sHeight / (float)dHeight;
+ float d = (float)sDepth / (float)dDepth;
+
+ float z = 0.5f * d;
+
+ for(int k = 0; k < dDepth; k++)
+ {
+ float y = 0.5f * h;
+
+ for(int j = 0; j < dHeight; j++)
+ {
+ float x = 0.5f * w;
+
+ for(int i = 0; i < dWidth; i++)
+ {
+ sw::Color<float> color;
+
+ if(filter <= D3DTEXF_POINT)
+ {
+ color = source->readInternal((int)x, (int)y, (int)z);
+ }
+ else // filter >= D3DTEXF_LINEAR
+ {
+ color = source->sampleInternal(x, y, z);
+ }
+
+ dest->writeInternal(i, j, k, color);
+
+ x += w;
+ }
+
+ y += h;
+ }
+
+ z += d;
+ }
+
+ source->unlockInternal();
+ dest->unlockInternal();
+ }
+
+ volumeLevel[0]->cleanMipmaps();
+
+ resource->unlock();
+ }
+
+ D3DTEXTUREFILTERTYPE Direct3DVolumeTexture9::GetAutoGenFilterType()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetAutoGenFilterType();
+ }
+
+ unsigned long Direct3DVolumeTexture9::GetLevelCount()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetLevelCount();
+ }
+
+ unsigned long Direct3DVolumeTexture9::GetLOD()
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::GetLOD();
+ }
+
+ long Direct3DVolumeTexture9::SetAutoGenFilterType(D3DTEXTUREFILTERTYPE filterType)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::SetAutoGenFilterType(filterType);
+ }
+
+ unsigned long Direct3DVolumeTexture9::SetLOD(unsigned long newLOD)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ return Direct3DBaseTexture9::SetLOD(newLOD);
+ }
+
+ long Direct3DVolumeTexture9::GetVolumeLevel(unsigned int level, IDirect3DVolume9 **volume)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ *volume = 0;
+
+ if(level >= GetLevelCount() || !volumeLevel[level])
+ {
+ return INVALIDCALL();
+ }
+
+ volumeLevel[level]->AddRef();
+ *volume = volumeLevel[level];
+
+ return D3D_OK;
+ }
+
+ long Direct3DVolumeTexture9::LockBox(unsigned int level, D3DLOCKED_BOX *lockedVolume, const D3DBOX *box, unsigned long flags)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!lockedVolume || level >= GetLevelCount() || !volumeLevel[level])
+ {
+ return INVALIDCALL();
+ }
+
+ return volumeLevel[level]->LockBox(lockedVolume, box, flags);
+ }
+
+ long Direct3DVolumeTexture9::UnlockBox(unsigned int level)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(level >= GetLevelCount() || !volumeLevel[level])
+ {
+ return INVALIDCALL();
+ }
+
+ return volumeLevel[level]->UnlockBox();
+ }
+
+ long Direct3DVolumeTexture9::AddDirtyBox(const D3DBOX *dirtyBox)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ // UNIMPLEMENTED();
+
+ return D3D_OK;
+ }
+
+ long Direct3DVolumeTexture9::GetLevelDesc(unsigned int level, D3DVOLUME_DESC *description)
+ {
+ CriticalSection cs(device);
+
+ TRACE("");
+
+ if(!description || level >= GetLevelCount() || !volumeLevel[level])
+ {
+ return INVALIDCALL();
+ }
+
+ return volumeLevel[level]->GetDesc(description);
+ }
+
+ Direct3DVolume9 *Direct3DVolumeTexture9::getInternalVolumeLevel(unsigned int level)
+ {
+ return volumeLevel[level];
+ }
+}
diff --git a/src/D3D9/Direct3DVolumeTexture9.hpp b/src/D3D9/Direct3DVolumeTexture9.hpp
new file mode 100644
index 0000000..1fa2447
--- /dev/null
+++ b/src/D3D9/Direct3DVolumeTexture9.hpp
@@ -0,0 +1,75 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Direct3DVolumeTexture9_hpp
+#define D3D9_Direct3DVolumeTexture9_hpp
+
+#include "Direct3DBaseTexture9.hpp"
+
+#include "Config.hpp"
+
+#include <d3d9.h>
+
+namespace D3D9
+{
+ class Direct3DVolume9;
+
+ class Direct3DVolumeTexture9 : public IDirect3DVolumeTexture9, public Direct3DBaseTexture9
+ {
+ public:
+ Direct3DVolumeTexture9(Direct3DDevice9 *device, unsigned int width, unsigned int height, unsigned int depth, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool);
+
+ virtual ~Direct3DVolumeTexture9();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // IDirect3DResource9 methods
+ long __stdcall GetDevice(IDirect3DDevice9 **device);
+ long __stdcall SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags);
+ long __stdcall GetPrivateData(const GUID &guid, void *data, unsigned long *size);
+ long __stdcall FreePrivateData(const GUID &guid);
+ unsigned long __stdcall SetPriority(unsigned long newPriority);
+ unsigned long __stdcall GetPriority();
+ void __stdcall PreLoad();
+ D3DRESOURCETYPE __stdcall GetType();
+
+ // IDirect3DBaseTexture9 methods
+ unsigned long __stdcall SetLOD(unsigned long newLOD);
+ unsigned long __stdcall GetLOD();
+ unsigned long __stdcall GetLevelCount();
+ long __stdcall SetAutoGenFilterType(D3DTEXTUREFILTERTYPE filterType);
+ D3DTEXTUREFILTERTYPE __stdcall GetAutoGenFilterType();
+ void __stdcall GenerateMipSubLevels();
+
+ // IDirect3DVolumeTexture9 methods
+ long __stdcall GetLevelDesc(unsigned int level, D3DVOLUME_DESC *description);
+ long __stdcall GetVolumeLevel(unsigned int level, IDirect3DVolume9 **volume);
+ long __stdcall LockBox(unsigned int level, D3DLOCKED_BOX *lockedVolume, const D3DBOX *box, unsigned long flags);
+ long __stdcall UnlockBox(unsigned int level);
+ long __stdcall AddDirtyBox(const D3DBOX *dirtyBox);
+
+ // Internal methods
+ Direct3DVolume9 *getInternalVolumeLevel(unsigned int level);
+
+ private:
+ // Creation parameters
+ const unsigned int width;
+ const unsigned int height;
+ const unsigned int depth;
+
+ Direct3DVolume9 *volumeLevel[MIPMAP_LEVELS];
+ };
+}
+
+#endif // D3D9_Direct3DVolumeTexture9_hpp
diff --git a/src/D3D9/SwiftShader.cpp b/src/D3D9/SwiftShader.cpp
new file mode 100644
index 0000000..ecf7e4b
--- /dev/null
+++ b/src/D3D9/SwiftShader.cpp
@@ -0,0 +1,105 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "SwiftShader.hpp"
+
+#include "Direct3D9.hpp"
+#include "Debug.hpp"
+
+#ifndef WIN32_LEAN_AND_MEAN
+ #define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#include <initguid.h>
+
+DEFINE_GUID(IID_SwiftShaderPrivateV1, 0x761954E6, 0xC357, 0x426d, 0xA6, 0x90, 0x00, 0x50, 0x56, 0xC0, 0x00, 0x08);
+
+extern SWFILTER maximumFilterQuality;
+extern SWFILTER maximumMipmapQuality;
+extern SWPERSPECTIVE perspectiveQuality;
+extern bool disableServer;
+
+namespace D3D9
+{
+ SwiftShader::SwiftShader(Direct3D9 *d3d9) : d3d9(d3d9)
+ {
+ InitValidationApp();
+ }
+
+ SwiftShader::~SwiftShader()
+ {
+ }
+
+ long SwiftShader::QueryInterface(const IID &iid, void **object)
+ {
+ TRACE("");
+
+ if(iid == IID_SwiftShaderPrivateV1 ||
+ iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long SwiftShader::AddRef()
+ {
+ TRACE("");
+
+ return Unknown::AddRef();
+ }
+
+ unsigned long SwiftShader::Release()
+ {
+ TRACE("");
+
+ return Unknown::Release();
+ }
+
+ long SwiftShader::RegisterLicenseKey(char *licenseKey)
+ {
+ TRACE("");
+
+ memset(validationKey, '\0', sizeof(validationKey));
+ strncpy(validationKey, licenseKey, strlen(licenseKey));
+
+ return D3D_OK;
+ }
+
+ long SwiftShader::SetControlSetting(SWSETTINGTYPE setting, unsigned long value)
+ {
+ switch(setting)
+ {
+ case SWS_MAXIMUMFILTERQUALITY:
+ maximumFilterQuality = (SWFILTER)value;
+ break;
+ case SWS_MAXIMUMMIPMAPQUALITY:
+ maximumMipmapQuality = (SWFILTER)value;
+ break;
+ case SWS_PERSPECTIVEQUALITY:
+ perspectiveQuality = (SWPERSPECTIVE)value;
+ break;
+ case SWS_DISABLESERVER:
+ disableServer = (value != FALSE);
+ break;
+ default:
+ ASSERT(false);
+ }
+
+ return D3D_OK;
+ }
+}
diff --git a/src/D3D9/SwiftShader.h b/src/D3D9/SwiftShader.h
new file mode 100644
index 0000000..b0340ad
--- /dev/null
+++ b/src/D3D9/SwiftShader.h
@@ -0,0 +1,134 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef _SWIFTSHADER_H_
+#define _SWIFTSHADER_H_
+
+#include "Register.hpp"
+
+#include <objbase.h>
+#include <stdlib.h>
+
+#define SWIFTSHADERAPI WINAPI
+
+/*
+ * Interface IID's
+ */
+#if defined( _WIN32 ) && !defined( _NO_COM)
+
+/* IID_SwiftShaderPrivateV1 */
+/* {761954E6-C357-11DA-A690-005056C00008} */
+DEFINE_GUID(IID_SwiftShaderPrivateV1, 0x761954E6, 0xC357, 0x426d, 0xA6, 0x90, 0x00, 0x50, 0x56, 0xC0, 0x00, 0x08);
+
+#endif
+
+#ifdef __cplusplus
+
+#ifndef DECLSPEC_UUID
+#if _MSC_VER >= 1100
+#define DECLSPEC_UUID(x) __declspec(uuid(x))
+#else
+#define DECLSPEC_UUID(x)
+#endif
+#endif
+
+interface DECLSPEC_UUID("761954E6-C357-11DA-A690-005056C00008") IID_SwiftShaderPrivateV1;
+
+
+#if defined(_COM_SMARTPTR_TYPEDEF)
+_COM_SMARTPTR_TYPEDEF(ISwiftShaderPrivateV1, __uuidof(ISwiftShaderPrivateV1));
+#endif
+#endif
+
+
+typedef interface ISwiftShaderPrivateV1 ISwiftShaderPrivateV1;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * SwiftShader Private interface
+ */
+
+typedef enum _SWSETTINGTYPE {
+ SWS_MAXIMUMFILTERQUALITY = 1, /* SWFILTER texture filtering quality */
+ SWS_MAXIMUMMIPMAPQUALITY = 2, /* SWFILTER mipmap filtering quality */
+ SWS_PERSPECTIVEQUALITY = 3, /* SWPERSPECTIVE perspective correction quality */
+ SWS_DISABLESERVER = 4, /* BOOL disable SwiftConfig server */
+ SWS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} SWSETTINGTYPE;
+
+typedef enum _SWFILTER {
+ SWF_DEFAULT = 0, /* Default filter quality (build dependent) */
+ SWF_NONE = 1, /* No filtering (texture/mipmap) */
+ SWF_POINT = 2, /* Point filtering (texture/mipmap) */
+ SWF_AVERAGE2 = 3, /* Averaging 2 point samples (texture) */
+ SWF_AVERAGE4 = 4, /* Averaging 4 point samples (texture) */
+ SWF_POLYGON = 5, /* Per-polygon mipmapping */
+ SWF_LINEAR = 6, /* (Bi)linear filtering (texture/mipamp) */
+ SWF_MAXIMUM = 7, /* No limitation on filter quality */
+ SWF_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} SWFILTER;
+
+typedef enum _SWPERSPECTIVE {
+ SWP_DEFAULT = 0, /* Default perspective correction quality */
+ SWP_NONE = 1, /* No perspective correction (affine texture mapping) */
+ SWP_FAST = 2, /* Fast low-precision perspective correction */
+ SWP_ACCURATE = 3, /* Slower high-precision perspective correction */
+ SWP_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} SWPERSPECTIVE;
+
+#undef INTERFACE
+#define INTERFACE ISwiftShaderPrivateV1
+
+DECLARE_INTERFACE_(ISwiftShaderPrivateV1, IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+
+ /*** ISwiftShaderPrivateV1 methods ***/
+ STDMETHOD(RegisterLicenseKey)(THIS_ char* pLicenseKey) PURE;
+ STDMETHOD(SetControlSetting)(THIS_ SWSETTINGTYPE Setting,DWORD Value) PURE;
+};
+
+typedef struct ISwiftShaderPrivateV1 *LPSWIFTSHADERPRIVATEV1, *LPSWIFTSHADERPRIVATEV1;
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+#define ISwiftShaderPrivateV1_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define ISwiftShaderPrivateV1_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define ISwiftShaderPrivateV1_Release(p) (p)->lpVtbl->Release(p)
+#define ISwiftShaderPrivateV1_RegisterLicenseKey(p,a) (p)->lpVtbl->RegisterLicenseKey(p,a)
+#else
+#define ISwiftShaderPrivateV1_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define ISwiftShaderPrivateV1_AddRef(p) (p)->AddRef()
+#define ISwiftShaderPrivateV1_Release(p) (p)->Release()
+#define ISwiftShaderPrivateV1_RegisterLicenseKey(p,a) (p)->RegisterLicenseKey(a)
+#endif
+
+
+
+/****************************************************************************
+ * Flags for SwiftShader
+ ****************************************************************************/
+#define SWIFTSHADER_SOME_RANDOM_FLAG 0x00000001L
+
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* _SWIFTSHADER_H_ */
+
diff --git a/src/D3D9/SwiftShader.hpp b/src/D3D9/SwiftShader.hpp
new file mode 100644
index 0000000..f9c4f84
--- /dev/null
+++ b/src/D3D9/SwiftShader.hpp
@@ -0,0 +1,44 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_SwiftShader_hpp
+#define D3D9_SwiftShader_hpp
+
+#include "SwiftShader.h"
+#include "Unknown.hpp"
+
+namespace D3D9
+{
+ class Direct3D9;
+
+ class SwiftShader : public ISwiftShaderPrivateV1, public Unknown
+ {
+ public:
+ SwiftShader(Direct3D9 *d3d9);
+
+ virtual ~SwiftShader();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // ISwiftShaderPrivateV1 methods
+ long __stdcall RegisterLicenseKey(char *licenseKey);
+ long __stdcall SetControlSetting(SWSETTINGTYPE setting, unsigned long value);
+
+ private:
+ // Creation parameters
+ Direct3D9 *const d3d9;
+ };
+}
+
+#endif // D3D9_SwiftShader_hpp
diff --git a/src/D3D9/Unknown.cpp b/src/D3D9/Unknown.cpp
new file mode 100644
index 0000000..191d44d
--- /dev/null
+++ b/src/D3D9/Unknown.cpp
@@ -0,0 +1,83 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "Unknown.hpp"
+
+#include "Debug.hpp"
+
+namespace D3D9
+{
+ Unknown::Unknown()
+ {
+ referenceCount = 0;
+ bindCount = 0;
+ }
+
+ Unknown::~Unknown()
+ {
+ ASSERT(referenceCount == 0);
+ ASSERT(bindCount == 0);
+ }
+
+ long Unknown::QueryInterface(const IID &iid, void **object)
+ {
+ if(iid == IID_IUnknown)
+ {
+ AddRef();
+ *object = this;
+
+ return S_OK;
+ }
+
+ *object = 0;
+
+ return NOINTERFACE(iid);
+ }
+
+ unsigned long Unknown::AddRef()
+ {
+ return InterlockedIncrement(&referenceCount);
+ }
+
+ unsigned long Unknown::Release()
+ {
+ int current = referenceCount;
+
+ if(referenceCount > 0)
+ {
+ current = InterlockedDecrement(&referenceCount);
+ }
+
+ if(referenceCount == 0 && bindCount == 0)
+ {
+ delete this;
+ }
+
+ return current;
+ }
+
+ void Unknown::bind()
+ {
+ InterlockedIncrement(&bindCount);
+ }
+
+ void Unknown::unbind()
+ {
+ ASSERT(bindCount > 0);
+
+ InterlockedDecrement(&bindCount);
+
+ if(referenceCount == 0 && bindCount == 0)
+ {
+ delete this;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/D3D9/Unknown.hpp b/src/D3D9/Unknown.hpp
new file mode 100644
index 0000000..c032cc9
--- /dev/null
+++ b/src/D3D9/Unknown.hpp
@@ -0,0 +1,41 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#ifndef D3D9_Unknown_hpp
+#define D3D9_Unknown_hpp
+
+#include <unknwn.h>
+
+namespace D3D9
+{
+ class Unknown : IUnknown
+ {
+ public:
+ Unknown();
+
+ virtual ~Unknown();
+
+ // IUnknown methods
+ long __stdcall QueryInterface(const IID &iid, void **object);
+ unsigned long __stdcall AddRef();
+ unsigned long __stdcall Release();
+
+ // Internal methods
+ virtual void bind();
+ virtual void unbind();
+
+ private:
+ volatile long referenceCount;
+ volatile long bindCount;
+ };
+}
+
+#endif // D3D9_Unknown_hpp
diff --git a/src/D3D9/d3d9.def b/src/D3D9/d3d9.def
new file mode 100644
index 0000000..eb6f535
--- /dev/null
+++ b/src/D3D9/d3d9.def
@@ -0,0 +1,18 @@
+LIBRARY D3D9
+EXPORTS
+ Direct3DShaderValidatorCreate9 @1
+ PSGPError @2
+ PSGPSampleTexture @3
+ D3DPERF_BeginEvent @4
+ D3DPERF_EndEvent @5
+ D3DPERF_GetStatus @6
+ D3DPERF_QueryRepeatFrame @7
+ D3DPERF_SetMarker @8
+ D3DPERF_SetOptions @9
+ D3DPERF_SetRegion @10
+ DebugSetLevel @11
+ DebugSetMute @12
+ Direct3DCreate9 @13
+ Direct3DCreate9Ex @14
+
+ Register
\ No newline at end of file
diff --git a/src/D3D9/resource.h b/src/D3D9/resource.h
new file mode 100644
index 0000000..4eae621
--- /dev/null
+++ b/src/D3D9/resource.h
@@ -0,0 +1,14 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by D3D9.rc
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif