#include "nine_pipe.h"
#include "nine_dump.h"
#include "util/u_math.h"
-#include "util/u_format.h"
+#include "util/format/u_format.h"
#include "util/u_dump.h"
#include "pipe/p_screen.h"
#define DBG_CHANNEL DBG_ADAPTER
+static bool
+has_sm3(struct pipe_screen *hal)
+{
+ return hal->get_param(hal, PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD) &&
+ hal->get_param(hal, PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES) &&
+ hal->get_param(hal, PIPE_CAP_VERTEX_SHADER_SATURATE);
+}
+
HRESULT
NineAdapter9_ctor( struct NineAdapter9 *This,
struct NineUnknownParams *pParams,
* as these are very old, we choose to drop support for them */
/* checks minimum requirements, most are vs3/ps3 strict requirements */
- if (!hal->get_param(hal, PIPE_CAP_SM3) ||
+ if (!has_sm3(hal) ||
hal->get_shader_param(hal, PIPE_SHADER_VERTEX,
PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE) < 256 * sizeof(float[4]) ||
hal->get_shader_param(hal, PIPE_SHADER_FRAGMENT,
hal->get_shader_param(hal, PIPE_SHADER_VERTEX,
PIPE_SHADER_CAP_MAX_INPUTS) < 16 ||
hal->get_shader_param(hal, PIPE_SHADER_FRAGMENT,
- PIPE_SHADER_CAP_MAX_INPUTS) < 10) {
+ PIPE_SHADER_CAP_MAX_INPUTS) < 10 ||
+ hal->get_shader_param(hal, PIPE_SHADER_FRAGMENT,
+ PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS) < 16) {
ERR("Your card is not supported by Gallium Nine. Minimum requirement "
"is >= r500, >= nv50, >= i965\n");
return D3DERR_DRIVERINTERNALERROR;
hr = NineAdapter9_GetScreen(This, DevType, &screen);
if (FAILED(hr)) { return hr; }
+ /* The display format is not handled in Nine. We always present an XRGB8888
+ * buffer (and the display server will eventually do the conversion). We probably
+ * don't need to check for anything for the adapter format support, since if the
+ * display server advertise support, it will likely be able to do the conversion.
+ * We do the approximation that a format is available in the display server if
+ * the format passes with NINE_BIND_BACKBUFFER_FLAGS */
dfmt = d3d9_to_pipe_format_checked(screen, AdapterFormat, PIPE_TEXTURE_2D,
1,
- PIPE_BIND_DISPLAY_TARGET |
- PIPE_BIND_SHARED, FALSE, FALSE);
+ NINE_BIND_BACKBUFFER_FLAGS, FALSE, FALSE);
bfmt = d3d9_to_pipe_format_checked(screen, BackBufferFormat, PIPE_TEXTURE_2D,
1,
- PIPE_BIND_DISPLAY_TARGET |
- PIPE_BIND_SHARED, FALSE, FALSE);
+ NINE_BIND_BACKBUFFER_FLAGS, FALSE, FALSE);
if (dfmt == PIPE_FORMAT_NONE || bfmt == PIPE_FORMAT_NONE) {
DBG("Unsupported Adapter/BackBufferFormat.\n");
return D3DERR_NOTAVAILABLE;
bind = 0;
if (Usage & D3DUSAGE_RENDERTARGET) bind |= PIPE_BIND_RENDER_TARGET;
- if (Usage & D3DUSAGE_DEPTHSTENCIL) bind |= PIPE_BIND_DEPTH_STENCIL;
+ 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 &&
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;
}
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_TRANSFER_READ |
- PIPE_BIND_TRANSFER_WRITE | PIPE_BIND_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) {
+ 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)
- *pQualityLevels = 1; /* gallium doesn't have quality levels */
+ 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;
}
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);
+ NINE_BIND_BACKBUFFER_FLAGS, FALSE, FALSE);
bfmt = d3d9_to_pipe_format_checked(screen, RenderTargetFormat,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_RENDER_TARGET, FALSE, FALSE);
+ NINE_BIND_BACKBUFFER_FLAGS, FALSE, FALSE);
if (RenderTargetFormat == D3DFMT_NULL)
bfmt = dfmt;
zsfmt = d3d9_to_pipe_format_checked(screen, DepthStencilFormat,
if (FAILED(hr)) { return hr; }
dfmt = d3d9_to_pipe_format_checked(screen, TargetFormat, PIPE_TEXTURE_2D, 1,
- PIPE_BIND_DISPLAY_TARGET |
- PIPE_BIND_SHARED, FALSE, FALSE);
+ NINE_BIND_BACKBUFFER_FLAGS, FALSE, FALSE);
bfmt = d3d9_to_pipe_format_checked(screen, SourceFormat, PIPE_TEXTURE_2D, 1,
- PIPE_BIND_DISPLAY_TARGET |
- PIPE_BIND_SHARED, FALSE, FALSE);
+ NINE_BIND_BACKBUFFER_FLAGS, FALSE, FALSE);
if (dfmt == PIPE_FORMAT_NONE || bfmt == PIPE_FORMAT_NONE) {
DBG("%s to %s not supported.\n",
pCaps->AdapterOrdinal = 0;
- pCaps->Caps = 0;
+ pCaps->Caps = D3DCAPS_READ_SCANLINE;
- pCaps->Caps2 = D3DCAPS2_CANMANAGERESOURCE |
+ pCaps->Caps2 = /* D3DCAPS2_CANMANAGERESOURCE | */
/* D3DCAPS2_CANSHARERESOURCE | */
/* D3DCAPS2_CANCALIBRATEGAMMA | */
D3DCAPS2_DYNAMICTEXTURES |
D3DPRESENT_INTERVAL_THREE |
D3DPRESENT_INTERVAL_FOUR |
D3DPRESENT_INTERVAL_IMMEDIATE;
- pCaps->CursorCaps = D3DCURSORCAPS_COLOR | D3DCURSORCAPS_LOWRES;
+ pCaps->CursorCaps = D3DCURSORCAPS_COLOR /* | D3DCURSORCAPS_LOWRES*/;
pCaps->DevCaps = D3DDEVCAPS_CANBLTSYSTONONLOCAL |
D3DDEVCAPS_CANRENDERAFTERFLIP |
D3DPMISCCAPS_TSSARGTEMP |
D3DPMISCCAPS_BLENDOP |
D3DPIPECAP(INDEP_BLEND_ENABLE, D3DPMISCCAPS_INDEPENDENTWRITEMASKS) |
- /*D3DPMISCCAPS_PERSTAGECONSTANT |*/ /* TODO */
- /*D3DPMISCCAPS_POSTBLENDSRGBCONVERT |*/ /* TODO */
+ D3DPMISCCAPS_PERSTAGECONSTANT |
+ /*D3DPMISCCAPS_POSTBLENDSRGBCONVERT |*/ /* TODO: advertise if Ex and dx10 able card */
D3DPMISCCAPS_FOGANDSPECULARALPHA | /* Note: documentation of the flag is wrong */
D3DPIPECAP(BLEND_EQUATION_SEPARATE, D3DPMISCCAPS_SEPARATEALPHABLEND) |
D3DPIPECAP(MIXED_COLORBUFFER_FORMATS, D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS) |
D3DPTEXTURECAPS_ALPHAPALETTE |
D3DPTEXTURECAPS_PERSPECTIVE |
D3DPTEXTURECAPS_PROJECTED |
- /*D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE |*/
+ D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE |
D3DPTEXTURECAPS_CUBEMAP |
D3DPTEXTURECAPS_VOLUMEMAP |
D3DNPIPECAP(NPOT_TEXTURES, D3DPTEXTURECAPS_POW2) |
D3DNPIPECAP(NPOT_TEXTURES, D3DPTEXTURECAPS_NONPOW2CONDITIONAL) |
D3DNPIPECAP(NPOT_TEXTURES, D3DPTEXTURECAPS_CUBEMAP_POW2) |
D3DNPIPECAP(NPOT_TEXTURES, D3DPTEXTURECAPS_VOLUMEMAP_POW2) |
- D3DPIPECAP(MAX_TEXTURE_2D_LEVELS, D3DPTEXTURECAPS_MIPMAP) |
+ D3DPIPECAP(MAX_TEXTURE_2D_SIZE, D3DPTEXTURECAPS_MIPMAP) |
D3DPIPECAP(MAX_TEXTURE_3D_LEVELS, D3DPTEXTURECAPS_MIPVOLUMEMAP) |
D3DPIPECAP(MAX_TEXTURE_CUBE_LEVELS, D3DPTEXTURECAPS_MIPCUBEMAP);
pCaps->LineCaps |= D3DLINECAPS_ANTIALIAS;
}
- pCaps->MaxTextureWidth =
- 1 << (screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
+ pCaps->MaxTextureWidth =screen->get_param(screen,
+ PIPE_CAP_MAX_TEXTURE_2D_SIZE);
pCaps->MaxTextureHeight = pCaps->MaxTextureWidth;
pCaps->MaxVolumeExtent =
1 << (screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS) - 1);
D3DSTENCILCAPS_INVERT |
D3DSTENCILCAPS_INCR |
D3DSTENCILCAPS_DECR |
- D3DPIPECAP(TWO_SIDED_STENCIL, D3DSTENCILCAPS_TWOSIDED);
+ D3DSTENCILCAPS_TWOSIDED;
pCaps->FVFCaps =
8 | /* 8 textures max */
pCaps->MaxTextureBlendStages = 8; /* XXX wine */
(DWORD)screen->get_param(screen, PIPE_CAP_BLEND_EQUATION_SEPARATE);
- pCaps->MaxSimultaneousTextures = screen->get_shader_param(screen,
- PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS);
- if (pCaps->MaxSimultaneousTextures > NINE_MAX_SAMPLERS_PS)
- pCaps->MaxSimultaneousTextures = NINE_MAX_SAMPLERS_PS;
+ pCaps->MaxSimultaneousTextures = 8;
pCaps->VertexProcessingCaps = D3DVTXPCAPS_TEXGEN |
- /*D3DVTXPCAPS_TEXGEN_SPHEREMAP |*/
+ D3DVTXPCAPS_TEXGEN_SPHEREMAP |
D3DVTXPCAPS_MATERIALSOURCE7 |
D3DVTXPCAPS_DIRECTIONALLIGHTS |
D3DVTXPCAPS_POSITIONALLIGHTS |
pCaps->MaxActiveLights = NINE_MAX_LIGHTS_ACTIVE; /* like GL_LIGHTi */
pCaps->MaxUserClipPlanes = PIPE_MAX_CLIP_PLANES;
pCaps->MaxVertexBlendMatrices = 4; /* 1 vec4 BLENDWEIGHT/INDICES input */
- pCaps->MaxVertexBlendMatrixIndex = 7; /* D3DTS_WORLDMATRIX(0..7) */
+ pCaps->MaxVertexBlendMatrixIndex = 8; /* D3DTS_WORLDMATRIX(0..8) */
pCaps->MaxPointSize = screen->get_paramf(screen, PIPE_CAPF_MAX_POINT_WIDTH);