st/nine: Refactor format d3d9 to pipe conversion

Move the checks of whether the format is supported
into a common place.
The advantage is that allows to handle when a d3d9
format can be mapped to several formats, and that
cards don't support all of them.

Reviewed-by: Tiziano Bacocco <tizbac2@gmail.com>
Signed-off-by: Axel Davy <axel.davy@ens.fr>
This commit is contained in:
Axel Davy 2015-01-10 14:58:03 +01:00
parent f8713b1bfd
commit 27e438e356
11 changed files with 136 additions and 77 deletions

View File

@ -204,19 +204,15 @@ NineAdapter9_CheckDeviceType( struct NineAdapter9 *This,
hr = NineAdapter9_GetScreen(This, DevType, &screen);
if (FAILED(hr)) { return hr; }
dfmt = d3d9_to_pipe_format(AdapterFormat);
bfmt = d3d9_to_pipe_format(BackBufferFormat);
dfmt = d3d9_to_pipe_format_checked(screen, AdapterFormat, PIPE_TEXTURE_2D,
1,
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SHARED, FALSE);
bfmt = d3d9_to_pipe_format_checked(screen, BackBufferFormat, PIPE_TEXTURE_2D,
1,
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SHARED, FALSE);
if (dfmt == PIPE_FORMAT_NONE || bfmt == PIPE_FORMAT_NONE) {
DBG("Invalid Adapter/BackBufferFormat.\n");
return D3DERR_NOTAVAILABLE;
}
if (!screen->is_format_supported(screen, dfmt, PIPE_TEXTURE_2D, 1,
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SHARED) ||
!screen->is_format_supported(screen, bfmt, PIPE_TEXTURE_2D, 1,
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SHARED)) {
DBG("Unsupported Adapter/BackBufferFormat.\n");
return D3DERR_NOTAVAILABLE;
}
@ -258,6 +254,7 @@ NineAdapter9_CheckDeviceFormat( struct NineAdapter9 *This,
enum pipe_format pf;
enum pipe_texture_target target;
unsigned bind = 0;
boolean srgb;
/* Check adapter format. */
@ -271,11 +268,10 @@ NineAdapter9_CheckDeviceFormat( struct NineAdapter9 *This,
hr = NineAdapter9_GetScreen(This, DeviceType, &screen);
if (FAILED(hr))
return hr;
pf = d3d9_to_pipe_format(AdapterFormat);
if (pf == PIPE_FORMAT_NONE ||
!screen->is_format_supported(screen, pf, PIPE_TEXTURE_2D, 0,
pf = d3d9_to_pipe_format_checked(screen, AdapterFormat, PIPE_TEXTURE_2D, 0,
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SHARED)) {
PIPE_BIND_SHARED, FALSE);
if (pf == PIPE_FORMAT_NONE) {
DBG("AdapterFormat %s not available.\n",
d3dformat_to_string(AdapterFormat));
return D3DERR_NOTAVAILABLE;
@ -330,12 +326,9 @@ NineAdapter9_CheckDeviceFormat( struct NineAdapter9 *This,
}
pf = d3d9_to_pipe_format(CheckFormat);
if (Usage & (D3DUSAGE_QUERY_SRGBREAD | D3DUSAGE_QUERY_SRGBWRITE))
pf = util_format_srgb(pf);
if (pf == PIPE_FORMAT_NONE ||
!screen->is_format_supported(screen, pf, target, 0, bind)) {
srgb = (Usage & (D3DUSAGE_QUERY_SRGBREAD | D3DUSAGE_QUERY_SRGBWRITE)) != 0;
pf = d3d9_to_pipe_format_checked(screen, CheckFormat, target, 0, bind, srgb);
if (pf == PIPE_FORMAT_NONE) {
DBG("NOT AVAILABLE\n");
return D3DERR_NOTAVAILABLE;
}
@ -362,7 +355,6 @@ NineAdapter9_CheckDeviceMultiSampleType( struct NineAdapter9 *This,
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),
@ -373,13 +365,11 @@ NineAdapter9_CheckDeviceMultiSampleType( struct NineAdapter9 *This,
if (FAILED(hr))
return hr;
pf = d3d9_to_pipe_format(SurfaceFormat);
bind = util_format_is_depth_or_stencil(pf) ?
PIPE_BIND_DEPTH_STENCIL : PIPE_BIND_RENDER_TARGET;
pf = d3d9_to_pipe_format_checked_no_bind(screen, SurfaceFormat,
PIPE_TEXTURE_2D,
MultiSampleType, FALSE);
if (pf == PIPE_FORMAT_NONE ||
!screen->is_format_supported(screen, pf, PIPE_TEXTURE_2D,
MultiSampleType, bind)) {
if (pf == PIPE_FORMAT_NONE) {
DBG("%s with %u samples not available.\n",
d3dformat_to_string(SurfaceFormat), MultiSampleType);
return D3DERR_NOTAVAILABLE;
@ -437,27 +427,23 @@ NineAdapter9_CheckDepthStencilMatch( struct NineAdapter9 *This,
hr = NineAdapter9_GetScreen(This, DeviceType, &screen);
if (FAILED(hr)) { return hr; }
dfmt = d3d9_to_pipe_format(AdapterFormat);
bfmt = d3d9_to_pipe_format(RenderTargetFormat);
dfmt = d3d9_to_pipe_format_checked(screen, AdapterFormat, PIPE_TEXTURE_2D, 0,
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SHARED, FALSE);
bfmt = d3d9_to_pipe_format_checked(screen, RenderTargetFormat,
PIPE_TEXTURE_2D, 0,
PIPE_BIND_RENDER_TARGET, FALSE);
if (RenderTargetFormat == D3DFMT_NULL)
bfmt = dfmt;
zsfmt = d3d9_to_pipe_format(DepthStencilFormat);
zsfmt = d3d9_to_pipe_format_checked(screen, DepthStencilFormat,
PIPE_TEXTURE_2D, 0,
PIPE_BIND_DEPTH_STENCIL, FALSE);
if (dfmt == PIPE_FORMAT_NONE ||
bfmt == PIPE_FORMAT_NONE ||
zsfmt == PIPE_FORMAT_NONE) {
return D3DERR_NOTAVAILABLE;
}
if (!screen->is_format_supported(screen, dfmt, PIPE_TEXTURE_2D, 0,
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SHARED) ||
!screen->is_format_supported(screen, bfmt, PIPE_TEXTURE_2D, 0,
PIPE_BIND_RENDER_TARGET) ||
!screen->is_format_supported(screen, zsfmt, PIPE_TEXTURE_2D, 0,
PIPE_BIND_DEPTH_STENCIL)) {
return D3DERR_NOTAVAILABLE;
}
return D3D_OK;
}
@ -484,17 +470,14 @@ NineAdapter9_CheckDeviceFormatConversion( struct NineAdapter9 *This,
hr = NineAdapter9_GetScreen(This, DeviceType, &screen);
if (FAILED(hr)) { return hr; }
dfmt = d3d9_to_pipe_format(TargetFormat);
bfmt = d3d9_to_pipe_format(SourceFormat);
dfmt = d3d9_to_pipe_format_checked(screen, TargetFormat, PIPE_TEXTURE_2D, 1,
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SHARED, FALSE);
bfmt = d3d9_to_pipe_format_checked(screen, SourceFormat, PIPE_TEXTURE_2D, 1,
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SHARED, FALSE);
if (dfmt == PIPE_FORMAT_NONE || bfmt == PIPE_FORMAT_NONE) {
return D3DERR_NOTAVAILABLE;
}
if (!screen->is_format_supported(screen, dfmt, PIPE_TEXTURE_2D, 1,
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SHARED) ||
!screen->is_format_supported(screen, bfmt, PIPE_TEXTURE_2D, 1,
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SHARED)) {
DBG("%s to %s not supported.\n",
d3dformat_to_string(SourceFormat),
d3dformat_to_string(TargetFormat));

View File

@ -57,11 +57,10 @@ NineCubeTexture9_ctor( struct NineCubeTexture9 *This,
if (Usage & D3DUSAGE_AUTOGENMIPMAP)
Levels = 0;
pf = d3d9_to_pipe_format(Format);
if (pf == PIPE_FORMAT_NONE ||
!screen->is_format_supported(screen, pf, PIPE_TEXTURE_CUBE, 0, PIPE_BIND_SAMPLER_VIEW)) {
pf = d3d9_to_pipe_format_checked(screen, Format, PIPE_TEXTURE_CUBE, 0,
PIPE_BIND_SAMPLER_VIEW, FALSE);
if (pf == PIPE_FORMAT_NONE)
return D3DERR_INVALIDCALL;
}
/* We support ATI1 and ATI2 hacks only for 2D textures */
if (Format == D3DFMT_ATI1 || Format == D3DFMT_ATI2)

View File

@ -957,7 +957,6 @@ create_zs_or_rt_surface(struct NineDevice9 *This,
user_assert(Pool != D3DPOOL_MANAGED, D3DERR_INVALIDCALL);
templ.target = PIPE_TEXTURE_2D;
templ.format = d3d9_to_pipe_format(Format);
templ.width0 = Width;
templ.height0 = Height;
templ.depth0 = 1;
@ -974,6 +973,9 @@ create_zs_or_rt_surface(struct NineDevice9 *This,
assert(type == 2);
break;
}
templ.format = d3d9_to_pipe_format_checked(screen, Format, templ.target,
templ.nr_samples, templ.bind,
FALSE);
desc.Format = Format;
desc.Type = D3DRTYPE_SURFACE;
@ -991,7 +993,7 @@ create_zs_or_rt_surface(struct NineDevice9 *This,
if (Pool == D3DPOOL_DEFAULT && Format != D3DFMT_NULL) {
/* resource_create doesn't return an error code, so check format here */
user_assert(CHECK_PIPE_RESOURCE_TEMPLATE(templ), D3DERR_INVALIDCALL);
user_assert(templ.format != PIPE_FORMAT_NONE, D3DERR_INVALIDCALL);
resource = screen->resource_create(screen, &templ);
user_assert(resource, D3DERR_OUTOFVIDEOMEMORY);
if (Discard_or_Lockable && (desc.Usage & D3DUSAGE_RENDERTARGET))

View File

@ -133,10 +133,6 @@ static INLINE float asfloat(DWORD value)
return u.f;
}
#define CHECK_PIPE_RESOURCE_TEMPLATE(t) \
screen->is_format_supported(screen, (t).format, (t).target, (t).nr_samples, (t).bind)
struct nine_range
{
struct nine_range *next;

View File

@ -258,7 +258,7 @@ const enum pipe_format nine_d3d9_to_pipe_format_map[120] =
[D3DFMT_A4R4G4B4] = PIPE_FORMAT_B4G4R4A4_UNORM,
[D3DFMT_R3G3B2] = PIPE_FORMAT_B2G3R3_UNORM,
[D3DFMT_A8] = PIPE_FORMAT_A8_UNORM,
[D3DFMT_A8R3G3B2] = PIPE_FORMAT_NONE
[D3DFMT_A8R3G3B2] = PIPE_FORMAT_NONE,
[D3DFMT_X4R4G4B4] = PIPE_FORMAT_B4G4R4X4_UNORM,
[D3DFMT_A2B10G10R10] = PIPE_FORMAT_R10G10B10A2_UNORM,
[D3DFMT_A8B8G8R8] = PIPE_FORMAT_R8G8B8A8_UNORM,

View File

@ -25,8 +25,10 @@
#include "d3d9.h"
#include "pipe/p_format.h"
#include "pipe/p_screen.h"
#include "pipe/p_state.h" /* pipe_box */
#include "util/u_rect.h"
#include "util/u_format.h"
#include "nine_helpers.h"
struct cso_context;
@ -174,7 +176,7 @@ pipe_to_d3d9_format(enum pipe_format format)
}
static INLINE enum pipe_format
d3d9_to_pipe_format(D3DFORMAT format)
d3d9_to_pipe_format_internal(D3DFORMAT format)
{
if (format <= D3DFMT_A2B10G10R10_XR_BIAS)
return nine_d3d9_to_pipe_format_map[format];
@ -209,6 +211,57 @@ d3d9_to_pipe_format(D3DFORMAT format)
}
}
#define format_check_internal(pipe_format) \
screen->is_format_supported(screen, pipe_format, target, \
sample_count, bindings)
static INLINE enum pipe_format
d3d9_to_pipe_format_checked(struct pipe_screen *screen,
D3DFORMAT format,
enum pipe_texture_target target,
unsigned sample_count,
unsigned bindings,
boolean srgb)
{
enum pipe_format result;
result = d3d9_to_pipe_format_internal(format);
if (result == PIPE_FORMAT_NONE)
return PIPE_FORMAT_NONE;
if (srgb)
result = util_format_srgb(result);
if (format_check_internal(result))
return result;
return PIPE_FORMAT_NONE;
}
/* same that above, but determines binding flags */
static INLINE enum pipe_format
d3d9_to_pipe_format_checked_no_bind(struct pipe_screen *screen,
D3DFORMAT format,
enum pipe_texture_target target,
unsigned sample_count,
boolean srgb)
{
enum pipe_format result;
unsigned bindings;
result = d3d9_to_pipe_format_internal(format);
if (result == PIPE_FORMAT_NONE)
return PIPE_FORMAT_NONE;
bindings = util_format_is_depth_or_stencil(result) ?
PIPE_BIND_DEPTH_STENCIL : PIPE_BIND_RENDER_TARGET;
if (srgb)
result = util_format_srgb(result);
if (format_check_internal(result))
return result;
return PIPE_FORMAT_NONE;
}
static INLINE const char *
d3dformat_to_string(D3DFORMAT fmt)
{

View File

@ -69,7 +69,6 @@ NineSurface9_ctor( struct NineSurface9 *This,
This->base.info.screen = pParams->device->screen;
This->base.info.target = PIPE_TEXTURE_2D;
This->base.info.format = d3d9_to_pipe_format(pDesc->Format);
This->base.info.width0 = pDesc->Width;
This->base.info.height0 = pDesc->Height;
This->base.info.depth0 = 1;
@ -79,6 +78,12 @@ NineSurface9_ctor( struct NineSurface9 *This,
This->base.info.usage = PIPE_USAGE_DEFAULT;
This->base.info.bind = PIPE_BIND_SAMPLER_VIEW;
This->base.info.flags = 0;
This->base.info.format = d3d9_to_pipe_format_checked(This->base.info.screen,
pDesc->Format,
This->base.info.target,
This->base.info.nr_samples,
This->base.info.bind,
FALSE);
if (pDesc->Usage & D3DUSAGE_RENDERTARGET)
This->base.info.bind |= PIPE_BIND_RENDER_TARGET;

View File

@ -195,7 +195,10 @@ NineSwapChain9_Resize( struct NineSwapChain9 *This,
newBufferCount = pParams->BackBufferCount +
(pParams->SwapEffect != D3DSWAPEFFECT_COPY);
pf = d3d9_to_pipe_format(pParams->BackBufferFormat);
pf = d3d9_to_pipe_format_checked(This->screen, pParams->BackBufferFormat,
PIPE_TEXTURE_2D, pParams->MultiSampleType,
PIPE_BIND_RENDER_TARGET, FALSE);
if (This->actx->linear_framebuffer ||
(pf != PIPE_FORMAT_B8G8R8X8_UNORM &&
pf != PIPE_FORMAT_B8G8R8A8_UNORM) ||
@ -284,12 +287,18 @@ NineSwapChain9_Resize( struct NineSwapChain9 *This,
}
for (i = 0; i < newBufferCount; ++i) {
tmplt.format = d3d9_to_pipe_format(pParams->BackBufferFormat);
tmplt.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_TRANSFER_READ |
PIPE_BIND_TRANSFER_WRITE | PIPE_BIND_RENDER_TARGET;
tmplt.nr_samples = pParams->MultiSampleType;
if (!has_present_buffers)
tmplt.bind |= PIPE_BIND_SHARED | PIPE_BIND_SCANOUT | PIPE_BIND_DISPLAY_TARGET;
tmplt.format = d3d9_to_pipe_format_checked(This->screen,
pParams->BackBufferFormat,
PIPE_TEXTURE_2D,
tmplt.nr_samples,
tmplt.bind, FALSE);
if (tmplt.format == PIPE_FORMAT_NONE)
return D3DERR_INVALIDCALL;
resource = This->screen->resource_create(This->screen, &tmplt);
if (!resource) {
DBG("Failed to create pipe_resource.\n");
@ -330,10 +339,17 @@ NineSwapChain9_Resize( struct NineSwapChain9 *This,
pipe_resource_reference(&resource, NULL);
}
if (pParams->EnableAutoDepthStencil) {
tmplt.format = d3d9_to_pipe_format(pParams->AutoDepthStencilFormat);
tmplt.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_TRANSFER_READ |
PIPE_BIND_TRANSFER_WRITE | PIPE_BIND_DEPTH_STENCIL;
tmplt.nr_samples = pParams->MultiSampleType;
tmplt.format = d3d9_to_pipe_format_checked(This->screen,
pParams->AutoDepthStencilFormat,
PIPE_TEXTURE_2D,
tmplt.nr_samples,
tmplt.bind,
FALSE);
if (tmplt.format == PIPE_FORMAT_NONE)
return D3DERR_INVALIDCALL;
resource = This->screen->resource_create(This->screen, &tmplt);
if (!resource) {

View File

@ -93,11 +93,10 @@ NineTexture9_ctor( struct NineTexture9 *This,
if (Usage & D3DUSAGE_AUTOGENMIPMAP)
Levels = 0;
pf = d3d9_to_pipe_format(Format);
if (Format != D3DFMT_NULL && (pf == PIPE_FORMAT_NONE ||
!screen->is_format_supported(screen, pf, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW))) {
pf = d3d9_to_pipe_format_checked(screen, Format, PIPE_TEXTURE_2D, 0,
PIPE_BIND_SAMPLER_VIEW, FALSE);
if (Format != D3DFMT_NULL && pf == PIPE_FORMAT_NONE)
return D3DERR_INVALIDCALL;
}
info->screen = screen;
info->target = PIPE_TEXTURE_2D;

View File

@ -92,7 +92,6 @@ NineVolume9_ctor( struct NineVolume9 *This,
This->info.screen = pParams->device->screen;
This->info.target = PIPE_TEXTURE_3D;
This->info.format = d3d9_to_pipe_format(pDesc->Format);
This->info.width0 = pDesc->Width;
This->info.height0 = pDesc->Height;
This->info.depth0 = pDesc->Depth;
@ -102,6 +101,14 @@ NineVolume9_ctor( struct NineVolume9 *This,
This->info.usage = PIPE_USAGE_DEFAULT;
This->info.bind = PIPE_BIND_SAMPLER_VIEW;
This->info.flags = 0;
This->info.format = d3d9_to_pipe_format_checked(This->info.screen,
pDesc->Format,
This->info.target,
This->info.nr_samples,
This->info.bind, FALSE);
if (This->info.format == PIPE_FORMAT_NONE)
return D3DERR_DRIVERINTERNALERROR;
This->stride = util_format_get_stride(This->info.format, pDesc->Width);
This->stride = align(This->stride, 4);

View File

@ -59,11 +59,10 @@ NineVolumeTexture9_ctor( struct NineVolumeTexture9 *This,
if (Usage & D3DUSAGE_AUTOGENMIPMAP)
Levels = 0;
pf = d3d9_to_pipe_format(Format);
if (pf == PIPE_FORMAT_NONE ||
!screen->is_format_supported(screen, pf, PIPE_TEXTURE_3D, 0, PIPE_BIND_SAMPLER_VIEW)) {
pf = d3d9_to_pipe_format_checked(screen, Format, PIPE_TEXTURE_3D, 0,
PIPE_BIND_SAMPLER_VIEW, FALSE);
if (pf == PIPE_FORMAT_NONE)
return D3DERR_INVALIDCALL;
}
/* We support ATI1 and ATI2 hacks only for 2D textures */
if (Format == D3DFMT_ATI1 || Format == D3DFMT_ATI2)