diff --git a/include/bgfx.h b/include/bgfx.h index 13de6d84b..470118e90 100644 --- a/include/bgfx.h +++ b/include/bgfx.h @@ -71,6 +71,8 @@ namespace bgfx #define BGFX_STATE_POINT_SIZE_SHIFT 44 #define BGFX_STATE_POINT_SIZE_MASK UINT64_C(0x000ff00000000000) +#define BGFX_STATE_SRGBWRITE UINT64_C(0x0010000000000000) + #define BGFX_STATE_NONE UINT64_C(0x0000000000000000) #define BGFX_STATE_MASK UINT64_C(0xffffffffffffffff) #define BGFX_STATE_DEFAULT (0 \ @@ -112,6 +114,7 @@ namespace bgfx #define BGFX_TEXTURE_MIP_POINT UINT32_C(0x00010000) #define BGFX_TEXTURE_MIP_SHIFT 16 #define BGFX_TEXTURE_MIP_MASK UINT32_C(0x00010000) +#define BGFX_TEXTURE_SRGB UINT32_C(0x00020000) #define BGFX_RENDER_TARGET_NONE UINT32_C(0x00000000) #define BGFX_RENDER_TARGET_COLOR_RGBA UINT32_C(0x00000001) @@ -121,6 +124,13 @@ namespace bgfx #define BGFX_RENDER_TARGET_DEPTH UINT32_C(0x00000100) #define BGFX_RENDER_TARGET_DEPTH_SHIFT 8 #define BGFX_RENDER_TARGET_DEPTH_MASK UINT32_C(0x0000ff00) +#define BGFX_RENDER_TARGET_MSAA_X2 UINT32_C(0x00010000) +#define BGFX_RENDER_TARGET_MSAA_X4 UINT32_C(0x00020000) +#define BGFX_RENDER_TARGET_MSAA_X8 UINT32_C(0x00030000) +#define BGFX_RENDER_TARGET_MSAA_X16 UINT32_C(0x00040000) +#define BGFX_RENDER_TARGET_MSAA_SHIFT 16 +#define BGFX_RENDER_TARGET_MSAA_MASK UINT32_C(0x00070000) +#define BGFX_RENDER_TARGET_SRGBWRITE UINT32_C(0x00080000) #define BGFX_RESET_NONE UINT32_C(0x00000000) #define BGFX_RESET_FULLSCREEN UINT32_C(0x00000001) diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 499e65c1b..c3c179bd3 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -730,7 +730,7 @@ namespace bgfx m_render->destroy(); } -#if BX_PLATFORM_WINDOWS +#if BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360 DWORD WINAPI renderThread(LPVOID) #else void* renderThread(void*) diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 8ba3a0166..b02f41bd2 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -118,6 +118,7 @@ namespace bgfx void release(Memory* _mem); void saveTga(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _data); const char* getAttribName(Attrib::Enum _attr); + bool renderFrame(); inline uint32_t uint16_min(uint16_t _a, uint16_t _b) { diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index fff5157e6..63a6d49fb 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -24,7 +24,7 @@ namespace bgfx 1, }; - static const D3DMULTISAMPLE_TYPE s_msaa[] = + static const D3DMULTISAMPLE_TYPE s_checkMsaa[] = { D3DMULTISAMPLE_NONE, D3DMULTISAMPLE_2_SAMPLES, @@ -33,6 +33,15 @@ namespace bgfx D3DMULTISAMPLE_16_SAMPLES, }; + static Msaa s_msaa[] = + { + { D3DMULTISAMPLE_NONE, 0 }, + { D3DMULTISAMPLE_2_SAMPLES, 0 }, + { D3DMULTISAMPLE_4_SAMPLES, 0 }, + { D3DMULTISAMPLE_8_SAMPLES, 0 }, + { D3DMULTISAMPLE_16_SAMPLES, 0 }, + }; + static const D3DBLEND s_blendFactor[] = { (D3DBLEND)0, // ignored @@ -106,7 +115,9 @@ namespace bgfx , m_fmtINTZ(false) , m_fmtRAWZ(false) , m_flags(BGFX_RESET_NONE) + , m_rtMsaa(false) { + m_rt.idx = invalidHandle; } void init() @@ -117,7 +128,7 @@ namespace bgfx m_params.BackBufferHeight = BGFX_DEFAULT_HEIGHT; m_params.BackBufferFormat = D3DFMT_X8R8G8B8; m_params.BackBufferCount = 1; - m_params.MultiSampleType = s_msaa[(m_flags&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT]; + m_params.MultiSampleType = D3DMULTISAMPLE_NONE; m_params.MultiSampleQuality = 0; m_params.EnableAutoDepthStencil = TRUE; m_params.AutoDepthStencilFormat = D3DFMT_D24S8; @@ -295,6 +306,34 @@ namespace bgfx m_initialized = false; } + void updateMsaa() + { + for (uint32_t ii = 1; ii < countof(s_checkMsaa); ++ii) + { + D3DMULTISAMPLE_TYPE msaa = s_checkMsaa[ii]; + DWORD quality; + + HRESULT hr = m_d3d9->CheckDeviceMultiSampleType(m_adapter + , m_deviceType + , m_params.BackBufferFormat + , m_params.Windowed + , msaa + , &quality + ); + + if (SUCCEEDED(hr) ) + { + s_msaa[ii].m_type = msaa; + s_msaa[ii].m_quality = uint32_imax(0, quality-1); + } + else + { + s_msaa[ii].m_type = D3DMULTISAMPLE_NONE; + s_msaa[ii].m_quality = 0; + } + } + } + void updateResolution(const Resolution& _resolution) { if (m_params.BackBufferWidth != _resolution.m_width @@ -321,16 +360,11 @@ namespace bgfx m_params.FullScreen_RefreshRateInHz = BGFX_RESET_FULLSCREEN == (m_flags&BGFX_RESET_FULLSCREEN_MASK) ? 60 : 0; m_params.PresentationInterval = !!(m_flags&BGFX_RESET_VSYNC) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; - D3DMULTISAMPLE_TYPE msaa = s_msaa[(m_flags&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT]; - HRESULT hr = m_d3d9->CheckDeviceMultiSampleType(m_adapter - , m_deviceType - , m_params.BackBufferFormat - , m_params.Windowed - , msaa - , NULL - ); + updateMsaa(); - m_params.MultiSampleType = SUCCEEDED(hr) ? msaa : D3DMULTISAMPLE_NONE; + Msaa& msaa = s_msaa[(m_flags&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT]; + m_params.MultiSampleType = msaa.m_type; + m_params.MultiSampleQuality = msaa.m_quality; preReset(); DX_CHECK(m_device->Reset(&m_params) ); @@ -338,9 +372,9 @@ namespace bgfx } } - void setRenderTarget(RenderTargetHandle _rt) + void setRenderTarget(RenderTargetHandle _rt, bool _msaa = true) { - if (_rt.idx == bgfx::invalidHandle) + if (_rt.idx == invalidHandle) { DX_CHECK(m_device->SetRenderTarget(0, m_backBufferColor) ); DX_CHECK(m_device->SetDepthStencilSurface(m_backBufferDepthStencil) ); @@ -348,9 +382,31 @@ namespace bgfx else { RenderTarget& renderTarget = m_renderTargets[_rt.idx]; - DX_CHECK(m_device->SetRenderTarget(0, renderTarget.m_color) ); + if (_msaa + && renderTarget.m_rt != NULL) + { + DX_CHECK(m_device->SetRenderTarget(0, renderTarget.m_rt) ); + } + else + { + DX_CHECK(m_device->SetRenderTarget(0, renderTarget.m_color) ); + } DX_CHECK(m_device->SetDepthStencilSurface(NULL != renderTarget.m_depth ? renderTarget.m_depth : m_backBufferDepthStencil) ); } + + if (m_rt.idx != invalidHandle + && m_rt.idx != _rt.idx + && m_rtMsaa) + { + RenderTarget& renderTarget = m_renderTargets[m_rt.idx]; + if (renderTarget.m_rt != NULL) + { + renderTarget.resolve(); + } + } + + m_rt = _rt; + m_rtMsaa = _msaa; } void setShaderConstantF(uint8_t _flags, uint16_t _regIndex, const float* _val, uint16_t _numRegs) @@ -566,6 +622,8 @@ namespace bgfx void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS]; TextVideoMem m_textVideoMem; + RenderTargetHandle m_rt; + bool m_rtMsaa; }; static RendererContext s_renderCtx; @@ -895,6 +953,7 @@ namespace bgfx m_minFilter = s_textureFilter[(_flags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT]; m_magFilter = s_textureFilter[(_flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT]; m_mipFilter = s_textureFilter[(_flags&BGFX_TEXTURE_MIP_MASK)>>BGFX_TEXTURE_MIP_SHIFT]; + m_srgb = (_flags&BGFX_TEXTURE_SRGB) == BGFX_TEXTURE_SRGB; Dds dds; @@ -1072,6 +1131,7 @@ namespace bgfx DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_MIPFILTER, m_mipFilter) ); DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSU, m_tau) ); DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSV, m_tav) ); + DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_SRGBTEXTURE, m_srgb) ); DX_CHECK(s_renderCtx.m_device->SetTexture(_stage, m_ptr) ); } @@ -1088,9 +1148,27 @@ namespace bgfx { if (0 != m_flags) { + m_msaa = s_msaa[(m_flags&BGFX_RENDER_TARGET_MSAA_MASK)>>BGFX_RENDER_TARGET_MSAA_SHIFT]; uint32_t colorFormat = (m_flags&BGFX_RENDER_TARGET_COLOR_MASK)>>BGFX_RENDER_TARGET_COLOR_SHIFT; uint32_t depthFormat = (m_flags&BGFX_RENDER_TARGET_DEPTH_MASK)>>BGFX_RENDER_TARGET_DEPTH_SHIFT; + // CheckDeviceFormat D3DUSAGE_SRGBWRITE + + if (D3DMULTISAMPLE_NONE != m_msaa.m_type) + { + DX_CHECK(s_renderCtx.m_device->CreateRenderTarget(m_width + , m_height + , s_colorFormat[colorFormat] + , m_msaa.m_type + , m_msaa.m_quality + , false + , &m_rt + , NULL + ) ); + + BGFX_FATAL(m_rt, bgfx::Fatal::D3D9_UnableToCreateRenderTarget, "Unable to create MSAA render target."); + } + if (0 < colorFormat) { DX_CHECK(s_renderCtx.m_device->CreateTexture(m_width @@ -1110,19 +1188,15 @@ namespace bgfx if (0 < depthFormat) { - DX_CHECK(s_renderCtx.m_device->CreateTexture(m_width - , m_height - , 1 - , D3DUSAGE_DEPTHSTENCIL - , s_depthFormat[depthFormat] // s_renderCtx.m_fmtDepth - , D3DPOOL_DEFAULT - , &m_depthTexture - , NULL - ) ); - - BGFX_FATAL(m_depthTexture, bgfx::Fatal::D3D9_UnableToCreateRenderTarget, "Unable to create depth render target."); - - DX_CHECK(m_depthTexture->GetSurfaceLevel(0, &m_depth)) ; + DX_CHECK(s_renderCtx.m_device->CreateDepthStencilSurface(m_width + , m_height + , s_depthFormat[depthFormat] // s_renderCtx.m_fmtDepth + , m_msaa.m_type + , m_msaa.m_quality + , FALSE + , &m_depth + , NULL + ) ); } } } @@ -1134,6 +1208,11 @@ namespace bgfx uint32_t colorFormat = (m_flags&BGFX_RENDER_TARGET_COLOR_MASK)>>BGFX_RENDER_TARGET_COLOR_SHIFT; uint32_t depthFormat = (m_flags&BGFX_RENDER_TARGET_DEPTH_MASK)>>BGFX_RENDER_TARGET_DEPTH_SHIFT; + if (D3DMULTISAMPLE_NONE != m_msaa.m_type) + { + DX_RELEASE(m_rt, 0); + } + if (0 < colorFormat) { DX_RELEASE(m_color, 1); @@ -1142,8 +1221,7 @@ namespace bgfx if (0 < depthFormat) { - DX_RELEASE(m_depth, 1); - DX_RELEASE(m_depthTexture, 0); + DX_RELEASE(m_depth, 0); } } } @@ -1155,8 +1233,19 @@ namespace bgfx DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_MIPFILTER, D3DTEXF_POINT) ); DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP) ); DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP) ); + DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_SRGBTEXTURE, (m_flags&BGFX_RENDER_TARGET_SRGBWRITE) == BGFX_RENDER_TARGET_SRGBWRITE) ); DX_CHECK(s_renderCtx.m_device->SetTexture(_stage, m_colorTexture) ); } + + void RenderTarget::resolve() + { + DX_CHECK(s_renderCtx.m_device->StretchRect(m_rt + , NULL + , m_color + , NULL + , D3DTEXF_LINEAR + ) ); + } void ConstantBuffer::commit(bool _force) { @@ -1233,7 +1322,7 @@ namespace bgfx uint32_t height = s_renderCtx.m_params.BackBufferHeight; RenderTargetHandle rt = BGFX_INVALID_HANDLE; - s_renderCtx.setRenderTarget(rt); + s_renderCtx.setRenderTarget(rt, false); D3DVIEWPORT9 vp; vp.X = 0; @@ -1564,7 +1653,7 @@ namespace bgfx if ( (BGFX_STATE_CULL_MASK|BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK |BGFX_STATE_ALPHA_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE |BGFX_STATE_BLEND_MASK|BGFX_STATE_ALPHA_REF_MASK|BGFX_STATE_PT_MASK - |BGFX_STATE_POINT_SIZE_MASK) & changedFlags) + |BGFX_STATE_POINT_SIZE_MASK|BGFX_STATE_SRGBWRITE) & changedFlags) { if (BGFX_STATE_CULL_MASK & changedFlags) { @@ -1602,6 +1691,11 @@ namespace bgfx DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_POINTSIZE, *( (DWORD*)&pointSize) ) ); } + if (BGFX_STATE_SRGBWRITE & changedFlags) + { + DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_SRGBWRITEENABLE, (newFlags&BGFX_STATE_SRGBWRITE) == BGFX_STATE_SRGBWRITE) ); + } + if ( (BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE) & changedFlags) { uint32_t writeEnable = (newFlags&BGFX_STATE_ALPHA_WRITE) ? D3DCOLORWRITEENABLE_ALPHA : 0; diff --git a/src/renderer_d3d9.h b/src/renderer_d3d9.h index 98664a1c7..5f70fc4c8 100644 --- a/src/renderer_d3d9.h +++ b/src/renderer_d3d9.h @@ -61,9 +61,9 @@ typedef DWORD (WINAPI *D3DPERF_GetStatusFunc)(); # define D3DMULTISAMPLE_8_SAMPLES D3DMULTISAMPLE_4_SAMPLES # define D3DMULTISAMPLE_16_SAMPLES D3DMULTISAMPLE_4_SAMPLES -# define _PIX_SETMARKER(_col, _name) -# define _PIX_BEGINEVENT(_col, _name) -# define _PIX_ENDEVENT() +# define _PIX_SETMARKER(_col, _name) do {} while(0) +# define _PIX_BEGINEVENT(_col, _name) do {} while(0) +# define _PIX_ENDEVENT() do {} while(0) #endif // BX_PLATFORM_ namespace bgfx @@ -100,6 +100,12 @@ namespace bgfx } \ } while (0) + struct Msaa + { + D3DMULTISAMPLE_TYPE m_type; + DWORD m_quality; + }; + struct IndexBuffer { IndexBuffer() @@ -270,14 +276,15 @@ namespace bgfx D3DTEXTUREFILTERTYPE m_mipFilter; D3DTEXTUREADDRESS m_tau; D3DTEXTUREADDRESS m_tav; + bool m_srgb; }; struct RenderTarget { RenderTarget() - : m_colorTexture(NULL) + : m_rt(NULL) + , m_colorTexture(NULL) , m_color(NULL) - , m_depthTexture(NULL) , m_depth(NULL) , m_width(0) , m_height(0) @@ -306,10 +313,12 @@ namespace bgfx } void commit(uint8_t _stage); + void resolve(); + Msaa m_msaa; + IDirect3DSurface9* m_rt; IDirect3DTexture9* m_colorTexture; IDirect3DSurface9* m_color; - IDirect3DTexture9* m_depthTexture; IDirect3DSurface9* m_depth; uint16_t m_width; uint16_t m_height;