[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