HRESULT NINE_WINAPI NineAdapter9_CheckDepthStencilMatch( struct NineAdapter9 *This, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat ) { struct pipe_screen *screen; enum pipe_format dfmt, bfmt, zsfmt; HRESULT hr; DBG("This=%p DeviceType=%s AdapterFormat=%s " "RenderTargetFormat=%s DepthStencilFormat=%s\n", This, nine_D3DDEVTYPE_to_str(DeviceType), d3dformat_to_string(AdapterFormat), d3dformat_to_string(RenderTargetFormat), d3dformat_to_string(DepthStencilFormat)); user_assert(display_format(AdapterFormat, FALSE), D3DERR_NOTAVAILABLE); user_assert(depth_stencil_format(DepthStencilFormat), D3DERR_NOTAVAILABLE); hr = NineAdapter9_GetScreen(This, DeviceType, &screen); if (FAILED(hr)) { return hr; } dfmt = d3d9_to_pipe_format_checked(screen, AdapterFormat, PIPE_TEXTURE_2D, 0, PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SHARED, FALSE, FALSE); bfmt = d3d9_to_pipe_format_checked(screen, RenderTargetFormat, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET, FALSE, FALSE); if (RenderTargetFormat == D3DFMT_NULL) bfmt = dfmt; zsfmt = d3d9_to_pipe_format_checked(screen, DepthStencilFormat, PIPE_TEXTURE_2D, 0, d3d9_get_pipe_depth_format_bindings(DepthStencilFormat), FALSE, FALSE); if (dfmt == PIPE_FORMAT_NONE || bfmt == PIPE_FORMAT_NONE || zsfmt == PIPE_FORMAT_NONE) { return D3DERR_NOTAVAILABLE; } return D3D_OK; }
HRESULT WINAPI NineAdapter9_CheckDeviceMultiSampleType( struct NineAdapter9 *This, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD *pQualityLevels ) { struct pipe_screen *screen; HRESULT hr; enum pipe_format pf; unsigned bind; DBG("This=%p DeviceType=%s SurfaceFormat=%s Windowed=%i MultiSampleType=%u " "pQualityLevels=%p\n", This, nine_D3DDEVTYPE_to_str(DeviceType), d3dformat_to_string(SurfaceFormat), Windowed, MultiSampleType, pQualityLevels); hr = NineAdapter9_GetScreen(This, DeviceType, &screen); if (FAILED(hr)) return hr; if (depth_stencil_format(SurfaceFormat)) bind = d3d9_get_pipe_depth_format_bindings(SurfaceFormat); else /* render-target */ bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_TRANSFER_READ | PIPE_BIND_TRANSFER_WRITE | PIPE_BIND_RENDER_TARGET; pf = d3d9_to_pipe_format_checked(screen, SurfaceFormat, PIPE_TEXTURE_2D, MultiSampleType, bind, FALSE); if (pf == PIPE_FORMAT_NONE) { DBG("%s with %u samples not available.\n", d3dformat_to_string(SurfaceFormat), MultiSampleType); return D3DERR_NOTAVAILABLE; } if (pQualityLevels) *pQualityLevels = 1; /* gallium doesn't have quality levels */ return D3D_OK; }
HRESULT NINE_WINAPI NineAdapter9_CheckDeviceMultiSampleType( struct NineAdapter9 *This, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD *pQualityLevels ) { struct pipe_screen *screen; HRESULT hr; enum pipe_format pf; unsigned bind; DBG("This=%p DeviceType=%s SurfaceFormat=%s Windowed=%i MultiSampleType=%u " "pQualityLevels=%p\n", This, nine_D3DDEVTYPE_to_str(DeviceType), d3dformat_to_string(SurfaceFormat), Windowed, MultiSampleType, pQualityLevels); if (pQualityLevels) { /* In error cases return only 1 quality level supported */ *pQualityLevels = 1; } user_assert(MultiSampleType <= D3DMULTISAMPLE_16_SAMPLES, D3DERR_INVALIDCALL); hr = NineAdapter9_GetScreen(This, DeviceType, &screen); if (FAILED(hr)) return hr; if (depth_stencil_format(SurfaceFormat)) bind = d3d9_get_pipe_depth_format_bindings(SurfaceFormat); else /* render-target */ bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; pf = d3d9_to_pipe_format_checked(screen, SurfaceFormat, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, FALSE, FALSE); if (pf == PIPE_FORMAT_NONE && SurfaceFormat != D3DFMT_NULL) { DBG("%s not available.\n", d3dformat_to_string(SurfaceFormat)); return D3DERR_INVALIDCALL; } pf = d3d9_to_pipe_format_checked(screen, SurfaceFormat, PIPE_TEXTURE_2D, MultiSampleType, bind, FALSE, FALSE); if (pf == PIPE_FORMAT_NONE && SurfaceFormat != D3DFMT_NULL) { DBG("%s with %u samples not available.\n", d3dformat_to_string(SurfaceFormat), MultiSampleType); return D3DERR_NOTAVAILABLE; } if (pQualityLevels) { /* NONMASKABLE MultiSampleType might have more than one quality level, * while MASKABLE MultiSampleTypes have only one level. * Advertise quality levels and map each level to a sample count. */ (void ) d3dmultisample_type_check(screen, SurfaceFormat, &MultiSampleType, D3DMULTISAMPLE_16_SAMPLES, pQualityLevels); DBG("advertising %u quality levels\n", *pQualityLevels); } return D3D_OK; }
HRESULT NINE_WINAPI NineAdapter9_CheckDeviceFormat( struct NineAdapter9 *This, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat ) { struct pipe_screen *screen; HRESULT hr; enum pipe_format pf; enum pipe_texture_target target; unsigned bind = 0; boolean srgb; /* Check adapter format. */ DBG("This=%p DeviceType=%s AdapterFormat=%s\n", This, nine_D3DDEVTYPE_to_str(DeviceType), d3dformat_to_string(AdapterFormat)); DBG("Usage=%x RType=%u CheckFormat=%s\n", Usage, RType, d3dformat_to_string(CheckFormat)); user_assert(display_format(AdapterFormat, FALSE), D3DERR_INVALIDCALL); hr = NineAdapter9_GetScreen(This, DeviceType, &screen); if (FAILED(hr)) return hr; pf = d3d9_to_pipe_format_checked(screen, AdapterFormat, PIPE_TEXTURE_2D, 0, PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SHARED, FALSE, FALSE); if (pf == PIPE_FORMAT_NONE) { DBG("AdapterFormat %s not available.\n", d3dformat_to_string(AdapterFormat)); return D3DERR_NOTAVAILABLE; } /* Check actual format. */ switch (RType) { case D3DRTYPE_SURFACE: target = PIPE_TEXTURE_2D; break; case D3DRTYPE_TEXTURE: target = PIPE_TEXTURE_2D; break; case D3DRTYPE_CUBETEXTURE: target = PIPE_TEXTURE_CUBE; break; case D3DRTYPE_VOLUME: target = PIPE_TEXTURE_3D; break; case D3DRTYPE_VOLUMETEXTURE: target = PIPE_TEXTURE_3D; break; case D3DRTYPE_VERTEXBUFFER: target = PIPE_BUFFER; break; case D3DRTYPE_INDEXBUFFER: target = PIPE_BUFFER; break; default: user_assert(0, D3DERR_INVALIDCALL); } bind = 0; if (Usage & D3DUSAGE_RENDERTARGET) bind |= PIPE_BIND_RENDER_TARGET; if (Usage & D3DUSAGE_DEPTHSTENCIL) { if (!depth_stencil_format(CheckFormat)) return D3DERR_NOTAVAILABLE; bind |= d3d9_get_pipe_depth_format_bindings(CheckFormat); } /* API hack because setting RT[0] to NULL is forbidden */ if (CheckFormat == D3DFMT_NULL && bind == PIPE_BIND_RENDER_TARGET && (RType == D3DRTYPE_SURFACE || RType == D3DRTYPE_TEXTURE)) return D3D_OK; /* RESZ hack */ if (CheckFormat == D3DFMT_RESZ && bind == PIPE_BIND_RENDER_TARGET && RType == D3DRTYPE_SURFACE) return screen->get_param(screen, PIPE_CAP_MULTISAMPLE_Z_RESOLVE) ? D3D_OK : D3DERR_NOTAVAILABLE; /* ATOC hack */ if (CheckFormat == D3DFMT_ATOC && RType == D3DRTYPE_SURFACE) return D3D_OK; if ((Usage & D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) && (Usage & D3DUSAGE_RENDERTARGET)) bind |= PIPE_BIND_BLENDABLE; if (Usage & D3DUSAGE_DMAP) { DBG("D3DUSAGE_DMAP not available\n"); return D3DERR_NOTAVAILABLE; /* TODO: displacement mapping */ } switch (RType) { case D3DRTYPE_TEXTURE: bind |= PIPE_BIND_SAMPLER_VIEW; break; case D3DRTYPE_CUBETEXTURE: bind |= PIPE_BIND_SAMPLER_VIEW; break; case D3DRTYPE_VOLUMETEXTURE: bind |= PIPE_BIND_SAMPLER_VIEW; break; case D3DRTYPE_VERTEXBUFFER: bind |= PIPE_BIND_VERTEX_BUFFER; break; case D3DRTYPE_INDEXBUFFER: bind |= PIPE_BIND_INDEX_BUFFER; break; case D3DRTYPE_SURFACE: if (!(Usage & D3DUSAGE_DEPTHSTENCIL)) bind |= PIPE_BIND_SAMPLER_VIEW; /* StretchRect */ /* Offscreen surface support: Usage = 0. * In practice drivers are very restrictive on the formats supported. * Basically a few common formats + YUV and compressed formats. The * reason is that offscreen surface are useful only for directdraw * compatibility (a WONTIMPL of nine) + format conversion (useful in * particular for YUV because the format was not advertised for textures * on NV chips). */ if (Usage == 0) bind |= PIPE_BIND_RENDER_TARGET; /* A current requirement of our impl, which we should get rid of. */ default: break; } srgb = (Usage & (D3DUSAGE_QUERY_SRGBREAD | D3DUSAGE_QUERY_SRGBWRITE)) != 0; pf = d3d9_to_pipe_format_checked(screen, CheckFormat, target, 0, bind, srgb, FALSE); if (pf == PIPE_FORMAT_NONE) { DBG("NOT AVAILABLE\n"); return D3DERR_NOTAVAILABLE; } /* we support ATI1 and ATI2 hack only for 2D and Cube textures */ if (RType != D3DRTYPE_TEXTURE && RType != D3DRTYPE_CUBETEXTURE && (CheckFormat == D3DFMT_ATI1 || CheckFormat == D3DFMT_ATI2)) return D3DERR_NOTAVAILABLE; /* if (Usage & D3DUSAGE_NONSECURE) { don't know the implications of this } */ /* if (Usage & D3DUSAGE_SOFTWAREPROCESSING) { we can always support this } */ if ((Usage & D3DUSAGE_AUTOGENMIPMAP) && !(bind & PIPE_BIND_SAMPLER_VIEW)) return D3DOK_NOAUTOGEN; return D3D_OK; }