Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
O Direct3D suporta várias representações de ponto flutuante. Todos os cálculos de ponto flutuante operam sob um subconjunto definido das regras de ponto flutuante de precisão única de 32 bits IEEE 754.
Regras de ponto flutuante de 32 bits
Existem dois conjuntos de regras: as que estão em conformidade com o IEEE-754 e as que se desviam da norma.
Regras IEEE-754 honradas
Algumas dessas regras são uma única opção onde o IEEE-754 oferece opções.
Dividir por 0 produz +/- INF, exceto 0/0 que resulta em NaN.
logaritmo de (+/-) 0 produz -INF.
log de um valor negativo (diferente de -0) produz NaN.
A raiz quadrada recíproca (rsq) ou a raiz quadrada (sqrt) de um número negativo resulta em NaN.
A exceção é -0; sqrt(-0) produz -0 e rsq(-0) produz -INF.
INF - INF = NaN
(+/-)INF / (+/-)INF = NaN
(+/-)INF * 0 = NaN
NaN (qualquer OP) qualquer-valor = NaN
As comparações EQ, GT, GE, LT e LE, quando um ou ambos os operandos são NaN, retornam FALSE.
As comparações ignoram o sinal de 0 (portanto, +0 é igual a -0).
A comparação NE, quando um ou ambos os operandos são NaN, retorna TRUE.
As comparações de qualquer valor não-NaN com +/- INF retornam o resultado correto.
Desvios ou requisitos adicionais das regras IEEE-754
O IEEE-754 requer que as operações de ponto flutuante produzam um resultado que seja o valor representável mais próximo de um resultado infinitamente preciso, conhecido como arredondamento para o par mais próximo.
O Direct3D 11 e versões posteriores definem o mesmo requisito do IEEE-754: as operações de ponto flutuante de 32 bits produzem um resultado que está dentro de 0,5 unidade no último lugar (ULP) do resultado de precisão infinita. Isso significa que, por exemplo, o hardware pode truncar os resultados para 32 bits em vez de executar round-to-nearest-even, pois isso resultaria em erro de no máximo 0,5 ULP. Esta regra aplica-se apenas à adição, subtração e multiplicação.
Versões anteriores do Direct3D definem um requisito mais solto do que o IEEE-754: operações de ponto flutuante de 32 bits produzem um resultado que está dentro de uma unidade-último-lugar (1 ULP) do resultado infinitamente preciso. Isso significa que, por exemplo, o hardware pode truncar os resultados para 32 bits em vez de executar round-to-nearest-even, pois isso resultaria em erro de no máximo um ULP.
Não há suporte para exceções de ponto flutuante, bits de status ou armadilhas.
Os denormalizados são convertidos para zero com preservação do sinal na entrada e saída de qualquer operação matemática de ponto flutuante. Exceções são feitas para qualquer operação de E/S ou movimentação de dados que não manipule os dados.
Estados que contêm valores de ponto flutuante, como MinDepth/MaxDepth do Viewport ou valores de BorderColor, podem ser fornecidos como valores subnormalizados e podem ou não ser descartados antes que o hardware os utilize.
As operações mínimas ou máximas eliminam números desnormalizados para comparação, mas o resultado pode ou não ser um número desnormalizado eliminado.
A entrada NaN para uma operação sempre produz NaN na saída. Mas o padrão de bits exato do NaN não é necessário para permanecer o mesmo (a menos que a operação seja uma instrução de movimento bruto - que não altera os dados).
As operações Min ou max para as quais apenas um operando é NaN retornam o outro operando como resultado (ao contrário das regras de comparação que vimos anteriormente). Esta é uma regra IEEE 754R.
A especificação IEEE-754R para operações de ponto flutuante min e max afirma que se uma das entradas para min ou max é um valor QNaN silencioso, o resultado da operação é o outro parâmetro. Por exemplo:
min(x,QNaN) == min(QNaN,x) == x (same for max)Uma revisão da especificação IEEE-754R adotou um comportamento diferente para min e max quando uma entrada é um valor SNaN de "sinalização" versus um valor QNaN:
min(x,SNaN) == min(SNaN,x) == QNaN (same for max)Geralmente, o Direct3D segue os padrões aritméticos: IEEE-754 e IEEE-754R. Mas, neste caso, temos um desvio.
As regras aritméticas no Direct3D 10 e posteriores não fazem nenhuma distinção entre valores NaN silenciosos e de sinalização (QNaN versus SNaN). Todos os valores NaN são tratados da mesma maneira. No caso de min e max, o comportamento do Direct3D para qualquer valor NaN é como QNaN é tratado na definição IEEE-754R. (Para completar - se ambas as entradas forem NaN, qualquer valor NaN será retornado.)
Outra regra IEEE 754R é que min(-0,+0) == min(+0,-0) == -0, e max(-0,+0) == max(+0,-0) == +0, que honra o sinal, em contraste com as regras de comparação para zero assinado (como vimos anteriormente). O Direct3D recomenda o comportamento IEEE 754R aqui, mas não o impõe; É admissível que o resultado da comparação de zeros dependa da ordem dos parâmetros, usando uma comparação que ignora os sinais.
x*1.0f sempre resulta em x (exceto denorm flushed).
x/1.0f sempre resulta em x (exceto denorm flushed).
x +/- 0,0f sempre resulta em x (exceto denorm flushed). Mas -0 + 0 = +0.
Operações fundidas (como mad, dp3) produzem resultados que não são menos precisos do que a pior ordem serial possível de avaliação da expansão não fundida da operação. A definição da pior ordem possível, para efeitos de tolerância, não é uma definição fixa para uma dada operação fundida; depende dos valores particulares dos inputs. As fases individuais na expansão não fundida permitem um desvio de até 1 ULP (ou, para quaisquer instruções em que o Direct3D especifica uma tolerância menos rigorosa do que 1 ULP, é permitida a tolerância menos rigorosa).
As operações fundidas seguem as mesmas regras NaN que as operações não fundidas.
sqrt e rcp têm uma tolerância de 1 ULP. As instruções de raiz quadrada recíproca e recíproca do sombreador, rcp e rsq, têm seu próprio requisito de precisão relaxado separado.
Multiplicação e divisão operam no nível de precisão de ponto flutuante de 32 bits (precisão de 0,5 ULP para multiplicação, 1,0 ULP para inverso). Se x/y for implementado diretamente, os resultados devem ser de maior ou igual precisão do que um método de duas etapas.
Regras de ponto flutuante de 64 bits (precisão dupla)
Opcionalmente, os drivers de hardware e de vídeo suportam ponto flutuante de precisão dupla. Para indicar suporte, ao chamar ID3D11Device::CheckFeatureSupport com D3D11_FEATURE_DOUBLES, o driver atribui DoublePrecisionFloatShaderOps de D3D11_FEATURE_DATA_DOUBLES como TRUE. O driver e o hardware devem, portanto, suportar todas as instruções de ponto flutuante de precisão dupla.
As instruções de precisão dupla seguem os requisitos de comportamento do IEEE 754R.
É necessário suporte para geração de valores desnormalizados para dados de precisão dupla (sem comportamento flush-to-zero). Da mesma forma, as instruções não leem dados desnormalizados como um zero com sinal; honram o valor desnormalizado.
Regras de ponto flutuante de 16 bits
O Direct3D também suporta representações de 16 bits de números de vírgula flutuante.
Formato:
- 1 bit de sinal (s) na posição de bit mais significativo (MSB)
- 5 bits de expoente polarizado (e)
- 10 bits de fração (f), com um bit oculto adicional
Um valor float16 (v) segue estas regras:
- se e == 31 e f != 0, então v é NaN independentemente de s
- se e == 31 e f == 0, então v = (-1)s*infinito (infinito assinado)
- se e estiver entre 0 e 31, então v = (-1)s*2(e-15)*(1.f)
- se e == 0 e f != 0, então v = (-1)s*2(e-14)*(0.f) (números desnormalizados)
- Se e = 0 e f = 0, então v = (-1)s*0 (zero com sinal)
As regras de ponto flutuante de 32 bits também valem para números de ponto flutuante de 16 bits, ajustadas para o layout de bits descrito anteriormente. As exceções incluem:
- Precisão: As operações não fundidas em números de ponto flutuante de 16 bits produzem um resultado que é o valor representável mais próximo de um resultado infinitamente preciso (arredondar para o mais próximo par, conforme IEEE-754, aplicado a valores de 16 bits). As regras de ponto flutuante de 32 bits aderem a 1 tolerância ULP, as regras de ponto flutuante de 16 bits aderem a 0,5 ULP para operações não fundidas e 0,6 ULP para operações fundidas.
- Os números de vírgula flutuante de 16 bits preservam os números subnormais.
regras de ponto flutuante de 11 bits e 10 bits
O Direct3D também suporta formatos de ponto flutuante de 11 bits e 10 bits.
Formato:
- Sem bit de sinal
- 5 bits de expoente polarizado (e)
- 6 bits de fração (f) para um formato de 11 bits, 5 bits de fração (f) para um formato de 10 bits, com um bit oculto adicional em ambos os casos.
Um valor float11/float10 (v) segue as seguintes regras:
- se e == 31 e f != 0, então v é NaN
- se e == 31 e f == 0, então v = +infinito
- se e estiver entre 0 e 31, então v = 2(e-15)*(1.f)
- se e == 0 e f != 0, então v = *2(e-14)*(0.f) (números desnormalizados)
- se e == 0 e f == 0, então v = 0 (zero)
As regras de ponto flutuante de 32 bits também valem para números de ponto flutuante de 11 bits e 10 bits, ajustados para o layout de bits descrito anteriormente. As exceções incluem:
- Precisão: as regras de ponto flutuante de 32 bits sujeitam-se a 0,5 ULP.
- Os números de ponto flutuante de 10/11 bits preservam os números desnormalizados.
- Qualquer operação que resulte num número menor do que zero é limitada a zero.
Tópicos relacionados