[Mesa-dev] [PATCH 51/53] st/nine: Explicit nine requirements
Ilia Mirkin
imirkin at alum.mit.edu
Wed Jan 7 20:11:10 PST 2015
On Wed, Jan 7, 2015 at 11:37 AM, Axel Davy <axel.davy at ens.fr> wrote:
> This patch raises nine requirements and disables nine for old
> hw that don't match them.
>
> It would be possible to make a lot of things work with these hw,
> though not everything, but it needs special care for them in the
> code, and since they are very old, it's better to drop explicitly
> support for them. We are already having hard time supporting r500,
> which is the most flexible dx9-only card apparently.
>
> Signed-off-by: Axel Davy <axel.davy at ens.fr>
> ---
> src/gallium/state_trackers/nine/adapter9.c | 106 +++++++++++++++++------------
> src/gallium/state_trackers/nine/device9.c | 9 +--
> 2 files changed, 66 insertions(+), 49 deletions(-)
>
> diff --git a/src/gallium/state_trackers/nine/adapter9.c b/src/gallium/state_trackers/nine/adapter9.c
> index 481f863..b339e6e 100644
> --- a/src/gallium/state_trackers/nine/adapter9.c
> +++ b/src/gallium/state_trackers/nine/adapter9.c
> @@ -39,6 +39,7 @@ NineAdapter9_ctor( struct NineAdapter9 *This,
> struct NineUnknownParams *pParams,
> struct d3dadapter9_context *pCTX )
> {
> + struct pipe_screen *hal = pCTX->hal;
> HRESULT hr = NineUnknown_ctor(&This->base, pParams);
> if (FAILED(hr)) { return hr; }
>
> @@ -46,7 +47,7 @@ NineAdapter9_ctor( struct NineAdapter9 *This,
> nine_dump_D3DADAPTER_IDENTIFIER9(DBG_CHANNEL, &pCTX->identifier);
>
> This->ctx = pCTX;
> - if (!This->ctx->hal->get_param(This->ctx->hal, PIPE_CAP_CLIP_HALFZ)) {
> + if (!hal->get_param(hal, PIPE_CAP_CLIP_HALFZ)) {
> ERR("Driver doesn't support d3d9 coordinates\n");
> return D3DERR_DRIVERINTERNALERROR;
> }
> @@ -54,7 +55,44 @@ NineAdapter9_ctor( struct NineAdapter9 *This,
> !This->ctx->ref->get_param(This->ctx->ref, PIPE_CAP_CLIP_HALFZ)) {
> ERR("Warning: Sotware rendering driver doesn't support d3d9 coordinates\n");
> }
> -
> + /* Old cards had tricks to bypass some restrictions to implement
> + * everything and fit tight the requirements: number of constants,
> + * number of temp registers, special behaviours, etc. Since we don't
> + * have access to all this, we need a bit more than what dx9 required.
> + * For example we have to use more than 32 temp registers to emulate
> + * behaviours, while some dx9 hw don't have more. As for sm2 hardware,
> + * we could support vs2 / ps2 for them but it needs some more care, and
> + * 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) ||
> + 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,
> + PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE) < 244 * sizeof(float[4]) ||
> + hal->get_shader_param(hal, PIPE_SHADER_VERTEX,
> + PIPE_SHADER_CAP_MAX_TEMPS) < 32 ||
> + hal->get_shader_param(hal, PIPE_SHADER_FRAGMENT,
> + PIPE_SHADER_CAP_MAX_TEMPS) < 32 ||
> + 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) {
> + ERR("Your card is not supported by Gallium Nine. Minimum requirement"
add a space here so that it doesn't say "requirementis"
> + "is >= r500, >= nv50, >= i965\n");
> + return D3DERR_DRIVERINTERNALERROR;
> + }
> + /* for r500 */
> + if (hal->get_shader_param(hal, PIPE_SHADER_VERTEX,
> + PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE) < 276 * sizeof(float[4]) || /* we put bool and int constants with float constants */
> + hal->get_shader_param(hal, PIPE_SHADER_VERTEX,
> + PIPE_SHADER_CAP_MAX_TEMPS) < 40 || /* we use some more temp registers */
> + hal->get_shader_param(hal, PIPE_SHADER_FRAGMENT,
> + PIPE_SHADER_CAP_MAX_TEMPS) < 40 ||
> + hal->get_shader_param(hal, PIPE_SHADER_FRAGMENT,
> + PIPE_SHADER_CAP_MAX_INPUTS) < 20) /* we don't pack inputs as much as we could */
> + ERR("Your card is at the limit of Gallium Nine requirements. Some games"
add a space
> + "may run into issues because requirements are too tight\n");
> return D3D_OK;
> }
>
> @@ -472,7 +510,6 @@ NineAdapter9_GetDeviceCaps( struct NineAdapter9 *This,
> D3DCAPS9 *pCaps )
> {
> struct pipe_screen *screen;
> - boolean sm3, vs;
> HRESULT hr;
>
> DBG("This=%p DeviceType=%s pCaps=%p\n", This,
> @@ -492,10 +529,6 @@ NineAdapter9_GetDeviceCaps( struct NineAdapter9 *This,
> #define D3DNPIPECAP(pcap, d3dcap) \
> (screen->get_param(screen, PIPE_CAP_##pcap) ? 0 : (d3dcap))
>
> - sm3 = screen->get_param(screen, PIPE_CAP_SM3);
> - vs = !!(screen->get_shader_param(screen, PIPE_SHADER_VERTEX,
> - PIPE_SHADER_CAP_MAX_INSTRUCTIONS));
> -
> pCaps->DeviceType = DeviceType;
>
> pCaps->AdapterOrdinal = 0;
> @@ -781,28 +814,16 @@ NineAdapter9_GetDeviceCaps( struct NineAdapter9 *This,
> pCaps->MaxStreamStride = screen->get_param(screen,
> PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE);
>
> - pCaps->VertexShaderVersion = sm3 ? D3DVS_VERSION(3,0) : D3DVS_VERSION(2,0);
> - if (vs) {
> - /* VS 2 as well as 3.0 supports a minimum of 256 consts, no matter how
> - * much our architecture moans about it. The problem is that D3D9
> - * expects access to 16 int consts (i#), containing 3 components and
> - * 16 booleans (b#), containing only 1 component. This should be packed
> - * into 20 float vectors (16 for i# and 16/4 for b#), since gallium has
> - * removed support for the loop counter/boolean files. */
> - pCaps->MaxVertexShaderConst =
> - _min((screen->get_shader_param(screen, PIPE_SHADER_VERTEX,
> - PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE) /
> - sizeof(float[4])) - 20,
> - NINE_MAX_CONST_F);
> - /* Fake the minimum cap for Windows. */
> - if (QUIRK(FAKE_CAPS)) {
> - pCaps->MaxVertexShaderConst = 256;
> - }
> - } else {
> - pCaps->MaxVertexShaderConst = 0;
> - }
> + pCaps->VertexShaderVersion = D3DVS_VERSION(3,0);
> +
> + /* VS 2 as well as 3.0 supports a minimum of 256 consts.
> + * Wine and d3d9 drivers for dx1x hw advertise 256. Just as them,
> + * advertise 256. Problem is with hw that can only do 256, because
> + * we need take a few slots for boolean and integer constants. For these
> + * we'll have to fail later if they use complex shaders. */
> + pCaps->MaxVertexShaderConst = NINE_MAX_CONST_F;
>
> - pCaps->PixelShaderVersion = sm3 ? D3DPS_VERSION(3,0) : D3DPS_VERSION(2,0);
> + pCaps->PixelShaderVersion = D3DPS_VERSION(3,0);
> pCaps->PixelShader1xMaxValue = 8.0f; /* XXX: wine */
>
> pCaps->DevCaps2 = D3DDEVCAPS2_STREAMOFFSET |
> @@ -919,23 +940,18 @@ NineAdapter9_GetDeviceCaps( struct NineAdapter9 *This,
> else
> pCaps->VertexTextureFilterCaps = 0;
>
> - if (sm3) {
> - pCaps->MaxVertexShader30InstructionSlots =
> - screen->get_shader_param(screen, PIPE_SHADER_VERTEX,
> - PIPE_SHADER_CAP_MAX_INSTRUCTIONS);
> - pCaps->MaxPixelShader30InstructionSlots =
> - screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT,
> - PIPE_SHADER_CAP_MAX_INSTRUCTIONS);
> - if (pCaps->MaxVertexShader30InstructionSlots > D3DMAX30SHADERINSTRUCTIONS)
> - pCaps->MaxVertexShader30InstructionSlots = D3DMAX30SHADERINSTRUCTIONS;
> - if (pCaps->MaxPixelShader30InstructionSlots > D3DMAX30SHADERINSTRUCTIONS)
> - pCaps->MaxPixelShader30InstructionSlots = D3DMAX30SHADERINSTRUCTIONS;
> - assert(pCaps->MaxVertexShader30InstructionSlots >= D3DMIN30SHADERINSTRUCTIONS);
> - assert(pCaps->MaxPixelShader30InstructionSlots >= D3DMIN30SHADERINSTRUCTIONS);
> - } else {
> - pCaps->MaxVertexShader30InstructionSlots = 0;
> - pCaps->MaxPixelShader30InstructionSlots = 0;
> - }
> + pCaps->MaxVertexShader30InstructionSlots =
> + screen->get_shader_param(screen, PIPE_SHADER_VERTEX,
> + PIPE_SHADER_CAP_MAX_INSTRUCTIONS);
> + pCaps->MaxPixelShader30InstructionSlots =
> + screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT,
> + PIPE_SHADER_CAP_MAX_INSTRUCTIONS);
> + if (pCaps->MaxVertexShader30InstructionSlots > D3DMAX30SHADERINSTRUCTIONS)
> + pCaps->MaxVertexShader30InstructionSlots = D3DMAX30SHADERINSTRUCTIONS;
> + if (pCaps->MaxPixelShader30InstructionSlots > D3DMAX30SHADERINSTRUCTIONS)
> + pCaps->MaxPixelShader30InstructionSlots = D3DMAX30SHADERINSTRUCTIONS;
> + assert(pCaps->MaxVertexShader30InstructionSlots >= D3DMIN30SHADERINSTRUCTIONS);
> + assert(pCaps->MaxPixelShader30InstructionSlots >= D3DMIN30SHADERINSTRUCTIONS);
>
> /* 65535 is required, advertise more for GPUs with >= 2048 instruction slots */
> pCaps->MaxVShaderInstructionsExecuted = MAX2(65535, pCaps->MaxVertexShader30InstructionSlots * 32);
> diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c
> index 98f0965..e213bbd 100644
> --- a/src/gallium/state_trackers/nine/device9.c
> +++ b/src/gallium/state_trackers/nine/device9.c
> @@ -248,14 +248,15 @@ NineDevice9_ctor( struct NineDevice9 *This,
> struct pipe_resource tmpl;
> unsigned max_const_vs, max_const_ps;
>
> + /* vs 3.0: >= 256 float constants, but for cards with exactly 256 slots,
> + * we have to take in some more slots for int and bool*/
> max_const_vs = _min(pScreen->get_shader_param(pScreen, PIPE_SHADER_VERTEX,
> PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE) /
> sizeof(float[4]),
> - NINE_MAX_CONST_ALL);
> - max_const_ps = _min(pScreen->get_shader_param(pScreen, PIPE_SHADER_FRAGMENT,
> - PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE) /
> - sizeof(float[4]),
> NINE_MAX_CONST_ALL);
> + /* ps 3.0: 224 float constants. All cards supported support at least
> + * 256 constants for ps */
> + max_const_ps = 224 + (NINE_MAX_CONST_I + NINE_MAX_CONST_B / 4);
>
> This->max_vs_const_f = max_const_vs -
> (NINE_MAX_CONST_I + NINE_MAX_CONST_B / 4);
> --
> 2.1.3
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list