bgfx/src/renderer_d3d9.h

471 lines
10 KiB
C
Raw Normal View History

2012-11-26 10:14:47 +04:00
/*
2016-01-01 11:11:04 +03:00
* Copyright 2011-2016 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
2012-11-26 10:14:47 +04:00
*/
#ifndef BGFX_RENDERER_D3D9_H_HEADER_GUARD
#define BGFX_RENDERER_D3D9_H_HEADER_GUARD
2012-11-26 10:14:47 +04:00
2015-10-30 06:41:19 +03:00
#define BGFX_CONFIG_RENDERER_DIRECT3D9EX BX_PLATFORM_WINDOWS
2012-11-26 10:14:47 +04:00
#if BX_PLATFORM_WINDOWS
2015-08-20 04:33:56 +03:00
# include <sal.h>
2012-11-26 10:14:47 +04:00
# include <d3d9.h>
#elif BX_PLATFORM_XBOX360
# include <xgraphics.h>
# define D3DUSAGE_DYNAMIC 0 // not supported on X360
# define D3DLOCK_DISCARD 0 // not supported on X360
# define D3DERR_DEVICEHUNG D3DERR_DEVICELOST // not supported on X360
# define D3DERR_DEVICEREMOVED D3DERR_DEVICELOST // not supported on X360
# define D3DMULTISAMPLE_8_SAMPLES D3DMULTISAMPLE_4_SAMPLES
# define D3DMULTISAMPLE_16_SAMPLES D3DMULTISAMPLE_4_SAMPLES
# define D3DFMT_DF24 D3DFMT_D24FS8
2014-06-09 07:57:39 +04:00
# define _PIX_SETMARKER(_col, _name) BX_NOOP()
# define _PIX_BEGINEVENT(_col, _name) BX_NOOP()
# define _PIX_ENDEVENT() BX_NOOP
2012-11-26 10:14:47 +04:00
#endif // BX_PLATFORM_
2013-07-27 09:55:13 +04:00
#ifndef D3DSTREAMSOURCE_INDEXEDDATA
# define D3DSTREAMSOURCE_INDEXEDDATA (1<<30)
#endif// D3DSTREAMSOURCE_INDEXEDDATA
#ifndef D3DSTREAMSOURCE_INSTANCEDATA
# define D3DSTREAMSOURCE_INSTANCEDATA (2<<30)
#endif // D3DSTREAMSOURCE_INSTANCEDATA
2014-12-28 06:00:41 +03:00
#include "renderer.h"
2012-11-26 10:14:47 +04:00
#include "renderer_d3d.h"
namespace bgfx { namespace d3d9
2012-11-26 10:14:47 +04:00
{
# if defined(D3D_DISABLE_9EX)
# define D3DFMT_S8_LOCKABLE D3DFORMAT( 85)
# define D3DFMT_A1 D3DFORMAT(118)
# endif // defined(D3D_DISABLE_9EX)
2012-11-26 10:14:47 +04:00
# ifndef D3DFMT_ATI1
# define D3DFMT_ATI1 ( (D3DFORMAT)BX_MAKEFOURCC('A', 'T', 'I', '1') )
2012-11-26 10:14:47 +04:00
# endif // D3DFMT_ATI1
# ifndef D3DFMT_ATI2
# define D3DFMT_ATI2 ( (D3DFORMAT)BX_MAKEFOURCC('A', 'T', 'I', '2') )
2012-11-26 10:14:47 +04:00
# endif // D3DFMT_ATI2
# ifndef D3DFMT_ATOC
# define D3DFMT_ATOC ( (D3DFORMAT)BX_MAKEFOURCC('A', 'T', 'O', 'C') )
2012-11-26 10:14:47 +04:00
# endif // D3DFMT_ATOC
# ifndef D3DFMT_DF16
# define D3DFMT_DF16 ( (D3DFORMAT)BX_MAKEFOURCC('D', 'F', '1', '6') )
2012-11-26 10:14:47 +04:00
# endif // D3DFMT_DF16
# ifndef D3DFMT_DF24
# define D3DFMT_DF24 ( (D3DFORMAT)BX_MAKEFOURCC('D', 'F', '2', '4') )
2012-11-26 10:14:47 +04:00
# endif // D3DFMT_DF24
# ifndef D3DFMT_INST
# define D3DFMT_INST ( (D3DFORMAT)BX_MAKEFOURCC('I', 'N', 'S', 'T') )
2012-11-26 10:14:47 +04:00
# endif // D3DFMT_INST
# ifndef D3DFMT_INTZ
# define D3DFMT_INTZ ( (D3DFORMAT)BX_MAKEFOURCC('I', 'N', 'T', 'Z') )
2012-11-26 10:14:47 +04:00
# endif // D3DFMT_INTZ
# ifndef D3DFMT_NULL
# define D3DFMT_NULL ( (D3DFORMAT)BX_MAKEFOURCC('N', 'U', 'L', 'L') )
2012-11-26 10:14:47 +04:00
# endif // D3DFMT_NULL
# ifndef D3DFMT_RESZ
# define D3DFMT_RESZ ( (D3DFORMAT)BX_MAKEFOURCC('R', 'E', 'S', 'Z') )
2012-11-26 10:14:47 +04:00
# endif // D3DFMT_RESZ
# ifndef D3DFMT_RAWZ
# define D3DFMT_RAWZ ( (D3DFORMAT)BX_MAKEFOURCC('R', 'A', 'W', 'Z') )
2012-11-26 10:14:47 +04:00
# endif // D3DFMT_RAWZ
2015-01-05 03:23:00 +03:00
# ifndef D3DFMT_S8_LOCKABLE
# define D3DFMT_S8_LOCKABLE ( (D3DFORMAT)85)
# endif // D3DFMT_S8_LOCKABLE
# ifndef D3DFMT_A1
# define D3DFMT_A1 ( (D3DFORMAT)118)
# endif // D3DFMT_A1
2012-11-26 10:14:47 +04:00
struct ExtendedFormat
{
enum Enum
{
Ati1,
Ati2,
Df16,
Df24,
Inst,
Intz,
Null,
Resz,
Rawz,
Count,
};
D3DFORMAT m_fmt;
DWORD m_usage;
D3DRESOURCETYPE m_type;
bool m_supported;
};
struct Msaa
{
D3DMULTISAMPLE_TYPE m_type;
DWORD m_quality;
};
struct IndexBufferD3D9
2012-11-26 10:14:47 +04:00
{
IndexBufferD3D9()
2012-11-26 10:14:47 +04:00
: m_ptr(NULL)
2015-04-09 05:59:48 +03:00
, m_size(0)
, m_flags(BGFX_BUFFER_NONE)
2012-11-26 10:14:47 +04:00
, m_dynamic(false)
{
}
2015-05-14 21:37:32 +03:00
void create(uint32_t _size, void* _data, uint16_t _flags);
2013-02-14 10:28:16 +04:00
void update(uint32_t _offset, uint32_t _size, void* _data, bool _discard = false)
2012-11-26 10:14:47 +04:00
{
void* buffer;
DX_CHECK(m_ptr->Lock(_offset
, _size
, &buffer
2013-02-14 10:28:16 +04:00
, _discard || (m_dynamic && 0 == _offset && m_size == _size) ? D3DLOCK_DISCARD : 0
2012-11-26 10:14:47 +04:00
) );
memcpy(buffer, _data, _size);
2015-01-27 06:09:51 +03:00
DX_CHECK(m_ptr->Unlock() );
2012-11-26 10:14:47 +04:00
}
void destroy()
{
if (NULL != m_ptr)
{
DX_RELEASE(m_ptr, 0);
m_dynamic = false;
}
}
void preReset();
void postReset();
IDirect3DIndexBuffer9* m_ptr;
uint32_t m_size;
2015-05-14 21:37:32 +03:00
uint16_t m_flags;
2012-11-26 10:14:47 +04:00
bool m_dynamic;
};
struct VertexBufferD3D9
2012-11-26 10:14:47 +04:00
{
VertexBufferD3D9()
2012-11-26 10:14:47 +04:00
: m_ptr(NULL)
, m_dynamic(false)
{
}
void create(uint32_t _size, void* _data, VertexDeclHandle _declHandle);
2013-02-14 10:28:16 +04:00
void update(uint32_t _offset, uint32_t _size, void* _data, bool _discard = false)
2012-11-26 10:14:47 +04:00
{
void* buffer;
DX_CHECK(m_ptr->Lock(_offset
, _size
, &buffer
2013-02-14 10:28:16 +04:00
, _discard || (m_dynamic && 0 == _offset && m_size == _size) ? D3DLOCK_DISCARD : 0
2012-11-26 10:14:47 +04:00
) );
memcpy(buffer, _data, _size);
2015-01-27 06:09:51 +03:00
DX_CHECK(m_ptr->Unlock() );
2012-11-26 10:14:47 +04:00
}
void destroy()
{
if (NULL != m_ptr)
{
DX_RELEASE(m_ptr, 0);
m_dynamic = false;
}
}
void preReset();
void postReset();
IDirect3DVertexBuffer9* m_ptr;
uint32_t m_size;
VertexDeclHandle m_decl;
bool m_dynamic;
};
2014-09-01 22:24:51 +04:00
struct VertexDeclD3D9
2012-11-26 10:14:47 +04:00
{
2014-09-01 22:24:51 +04:00
VertexDeclD3D9()
2013-09-21 09:13:58 +04:00
: m_ptr(NULL)
{
}
2012-11-26 10:14:47 +04:00
void create(const VertexDecl& _decl);
void destroy()
{
DX_RELEASE(m_ptr, 0);
}
IDirect3DVertexDeclaration9* m_ptr;
VertexDecl m_decl;
};
struct ShaderD3D9
2012-11-26 10:14:47 +04:00
{
ShaderD3D9()
2014-07-21 07:27:13 +04:00
: m_vertexShader(NULL)
2013-09-21 09:13:58 +04:00
, m_constantBuffer(NULL)
, m_numPredefined(0)
2014-07-21 07:27:13 +04:00
, m_type(0)
2012-11-26 10:14:47 +04:00
{
}
void create(const Memory* _mem);
2012-11-26 10:14:47 +04:00
DWORD* getShaderCode(uint8_t _fragmentBit, const Memory* _mem);
void destroy()
{
2013-09-21 09:13:58 +04:00
if (NULL != m_constantBuffer)
{
2015-09-15 01:53:33 +03:00
UniformBuffer::destroy(m_constantBuffer);
2013-09-21 09:13:58 +04:00
m_constantBuffer = NULL;
}
2012-11-26 10:14:47 +04:00
m_numPredefined = 0;
2014-07-21 07:27:13 +04:00
switch (m_type)
{
case 0: DX_RELEASE(m_vertexShader, 0);
default: DX_RELEASE(m_pixelShader, 0);
}
2012-11-26 10:14:47 +04:00
}
2014-07-21 07:27:13 +04:00
union
{
// X360 doesn't have interface inheritance (can't use IUnknown*).
IDirect3DVertexShader9* m_vertexShader;
IDirect3DPixelShader9* m_pixelShader;
};
2015-09-15 01:53:33 +03:00
UniformBuffer* m_constantBuffer;
2012-11-26 10:14:47 +04:00
PredefinedUniform m_predefined[PredefinedUniform::Count];
uint8_t m_numPredefined;
2014-07-21 07:27:13 +04:00
uint8_t m_type;
2012-11-26 10:14:47 +04:00
};
struct ProgramD3D9
2012-11-26 10:14:47 +04:00
{
void create(const ShaderD3D9& _vsh, const ShaderD3D9& _fsh)
2012-11-26 10:14:47 +04:00
{
2014-07-21 07:27:13 +04:00
BX_CHECK(NULL != _vsh.m_vertexShader, "Vertex shader doesn't exist.");
2012-11-26 10:14:47 +04:00
m_vsh = &_vsh;
2014-07-21 07:27:13 +04:00
BX_CHECK(NULL != _fsh.m_pixelShader, "Fragment shader doesn't exist.");
2012-11-26 10:14:47 +04:00
m_fsh = &_fsh;
memcpy(&m_predefined[0], _vsh.m_predefined, _vsh.m_numPredefined*sizeof(PredefinedUniform) );
memcpy(&m_predefined[_vsh.m_numPredefined], _fsh.m_predefined, _fsh.m_numPredefined*sizeof(PredefinedUniform) );
m_numPredefined = _vsh.m_numPredefined + _fsh.m_numPredefined;
}
void destroy()
{
m_numPredefined = 0;
m_vsh = NULL;
m_fsh = NULL;
}
const ShaderD3D9* m_vsh;
const ShaderD3D9* m_fsh;
2012-11-26 10:14:47 +04:00
PredefinedUniform m_predefined[PredefinedUniform::Count*2];
uint8_t m_numPredefined;
};
struct TextureD3D9
2012-11-26 10:14:47 +04:00
{
enum Enum
{
Texture2D,
Texture3D,
TextureCube,
};
TextureD3D9()
2012-11-26 10:14:47 +04:00
: m_ptr(NULL)
2014-02-06 11:07:11 +04:00
, m_surface(NULL)
2015-10-23 07:30:55 +03:00
, m_staging(NULL)
2014-02-06 11:07:11 +04:00
, m_textureFormat(TextureFormat::Unknown)
2012-11-26 10:14:47 +04:00
{
}
2014-02-06 11:07:11 +04:00
void createTexture(uint32_t _width, uint32_t _height, uint8_t _numMips);
2015-10-23 22:57:04 +03:00
void createVolumeTexture(uint32_t _width, uint32_t _height, uint32_t _depth, uint8_t _numMips);
void createCubeTexture(uint32_t _width, uint8_t _numMips);
2012-11-26 10:14:47 +04:00
uint8_t* lock(uint8_t _side, uint8_t _lod, uint32_t& _pitch, uint32_t& _slicePitch, const Rect* _rect = NULL);
void unlock(uint8_t _side, uint8_t _lod);
2013-03-03 11:20:28 +04:00
void dirty(uint8_t _side, const Rect& _rect, uint16_t _z, uint16_t _depth);
2015-10-20 01:09:56 +03:00
IDirect3DSurface9* getSurface(uint8_t _side = 0, uint8_t _mip = 0) const;
2012-11-26 10:14:47 +04:00
void create(const Memory* _mem, uint32_t _flags, uint8_t _skip);
2012-11-26 10:14:47 +04:00
void destroy()
{
2016-01-28 01:50:57 +03:00
if (0 == (m_flags & BGFX_TEXTURE_INTERNAL_SHARED) )
{
DX_RELEASE(m_ptr, 0);
}
2014-02-06 11:07:11 +04:00
DX_RELEASE(m_surface, 0);
2015-10-23 07:30:55 +03:00
DX_RELEASE(m_staging, 0);
2014-02-06 11:07:11 +04:00
m_textureFormat = TextureFormat::Unknown;
2012-11-26 10:14:47 +04:00
}
2016-01-28 01:50:57 +03:00
void overrideInternal(uintptr_t _ptr)
{
destroy();
m_flags |= BGFX_TEXTURE_INTERNAL_SHARED;
m_ptr = (IDirect3DBaseTexture9*)_ptr;
}
void updateBegin(uint8_t _side, uint8_t _mip);
void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem);
void updateEnd();
2015-09-17 03:21:28 +03:00
void commit(uint8_t _stage, uint32_t _flags, const float _palette[][4]);
2014-02-06 11:07:11 +04:00
void resolve() const;
void preReset();
void postReset();
2015-01-05 03:23:00 +03:00
2012-11-26 10:14:47 +04:00
union
{
2014-07-21 07:27:13 +04:00
IDirect3DBaseTexture9* m_ptr;
IDirect3DTexture9* m_texture2d;
2012-11-26 10:14:47 +04:00
IDirect3DVolumeTexture9* m_texture3d;
2014-07-21 07:27:13 +04:00
IDirect3DCubeTexture9* m_textureCube;
2012-11-26 10:14:47 +04:00
};
2014-02-06 11:07:11 +04:00
IDirect3DSurface9* m_surface;
2015-10-23 07:30:55 +03:00
union
{
IDirect3DBaseTexture9* m_staging;
IDirect3DTexture9* m_staging2d;
IDirect3DVolumeTexture9* m_staging3d;
IDirect3DCubeTexture9* m_stagingCube;
};
2015-11-02 04:28:23 +03:00
uint32_t m_flags;
2015-10-19 07:27:49 +03:00
uint32_t m_width;
uint32_t m_height;
uint32_t m_depth;
2014-02-06 11:07:11 +04:00
uint8_t m_numMips;
uint8_t m_type;
uint8_t m_requestedFormat;
uint8_t m_textureFormat;
2012-11-26 10:14:47 +04:00
};
struct FrameBufferD3D9
2012-11-26 10:14:47 +04:00
{
FrameBufferD3D9()
2014-09-08 04:17:38 +04:00
: m_hwnd(NULL)
, m_denseIdx(UINT16_MAX)
, m_num(0)
2014-02-06 11:07:11 +04:00
, m_needResolve(0)
2012-11-26 10:14:47 +04:00
{
2014-02-06 11:07:11 +04:00
m_depthHandle.idx = invalidHandle;
2012-11-26 10:14:47 +04:00
}
void create(uint8_t _num, const TextureHandle* _handles, const uint8_t* _side);
2014-09-08 04:17:38 +04:00
void create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat);
uint16_t destroy();
HRESULT present();
2014-02-06 11:07:11 +04:00
void resolve() const;
void preReset();
void postReset();
void createNullColorRT();
2012-11-26 10:14:47 +04:00
2014-02-06 11:07:11 +04:00
IDirect3DSurface9* m_color[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
IDirect3DSurface9* m_depthStencil;
2014-09-08 04:17:38 +04:00
IDirect3DSwapChain9* m_swapChain;
HWND m_hwnd;
2015-08-07 01:37:13 +03:00
uint32_t m_width;
uint32_t m_height;
2014-09-08 04:17:38 +04:00
2014-02-06 11:07:11 +04:00
TextureHandle m_colorHandle[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
TextureHandle m_depthHandle;
2014-09-08 04:17:38 +04:00
uint16_t m_denseIdx;
2014-02-06 11:07:11 +04:00
uint8_t m_num;
bool m_needResolve;
2012-11-26 10:14:47 +04:00
};
2015-05-13 03:03:25 +03:00
struct TimerQueryD3D9
{
TimerQueryD3D9()
: m_control(BX_COUNTOF(m_frame) )
{
}
2015-05-14 21:37:32 +03:00
void postReset();
void preReset();
2015-05-13 03:03:25 +03:00
void begin();
void end();
bool get();
struct Frame
{
IDirect3DQuery9* m_disjoint;
IDirect3DQuery9* m_begin;
2015-05-13 03:03:25 +03:00
IDirect3DQuery9* m_end;
IDirect3DQuery9* m_freq;
};
uint64_t m_begin;
uint64_t m_end;
2015-05-13 03:03:25 +03:00
uint64_t m_elapsed;
uint64_t m_frequency;
Frame m_frame[4];
bx::RingBufferControl m_control;
};
2015-11-02 04:28:23 +03:00
struct OcclusionQueryD3D9
{
OcclusionQueryD3D9()
: m_control(BX_COUNTOF(m_query) )
{
}
void postReset();
void preReset();
void begin(Frame* _render, OcclusionQueryHandle _handle);
2015-11-02 04:28:23 +03:00
void end();
void resolve(Frame* _render, bool _wait = false);
2015-11-02 04:28:23 +03:00
struct Query
{
IDirect3DQuery9* m_ptr;
OcclusionQueryHandle m_handle;
};
Query m_query[BGFX_CONFIG_MAX_OCCUSION_QUERIES];
bx::RingBufferControl m_control;
};
} /* namespace d3d9 */ } // namespace bgfx
2012-11-26 10:14:47 +04:00
#endif // BGFX_RENDERER_D3D9_H_HEADER_GUARD