Esto quería comentarlo hace unas semanas, se trata de la patente relacionada con Scarlett Cloud o más conocida por lo medios como Xbox Cloud.

La patente dice:

«El producto de la presente invención divide el procesamiento del juego y el renderizado entre un cliente y un servidor de juego. Una imagen renderizada de un videojuego es recibida desde un servidor de juego y combinada con la imagen renderizada generada por cliente de juego para formar una sola imagen de videojuego que es presentada al usuario final. El input de control es recibido por un dispositivo cliente y entonces comunidado al servidor de jugo, potencialmente con algo de preprocesamiento y también comunicado localmente en el cliente, al meno en parte. Una encarnación de la presente invención procesa y rendeirza todas las interecciones de lo personajes con lo objetos del juego asociadas con el personaje. Un personaje es asociado con un dispositivo cliente cuando la entrada de cntrol es recibida por un uuario en el dispositivo cliente.»


Basicamente para entender la patente hemos de entender que en cada fotograma la CPU ha de calcular la posición de cada objeto en pantalla calculando la detección de colisiones cuando dos objetos chocan y si se dan ciertas condiciones que provocan el cambio de estado de dichos objetos. Obviamente cuanto más complejo el espacio se necesita más carga de CPU y esta incluso tiene que calcular lo objetos con lo que el usuario no interacciona.

Estas interecciones entrelos objetos se suelen calcular actualmente utilizando el pipeline de computación de la GPU como pre-procesado del pipeline gráfico con tal de acelerar el trabajo. La patente lo que propone es que todos lo objetos de la escena que no interaccionen con el jugador sean procesados de forma remota por un servidor y que solo los elementos con los que interactua el jugador en cada fotograma son procesados a nivel de CPU en el sistema del usuario.

La patente nos lo muestra con una simpatica ilustración utilizando el Kinect, xD, pero que es lo suficientemente explicita para entender por donde van los tiros.

En realidad en dicha fase de pre-procesamiento todo el mecanismo es independiente de la resolución de pantalla hasta la fase de rasterización por lo que el calculo de la geometria es también independiente de resolución. ¿Pero realmente estamos hablando del renderizado compartido de manera literal? No, lo que yo pienso es que tanto cliente como servidor funcionan con una lista o tabla de todos los objetos de la escena, cuando el jugador ha acabado de interaccionar con los objetos producto de una pulsación de botón lo que hace la CPU es calcular la detección de colisiones de lo objetos que se encuentran interaccionando en primer grado, es decir, en grado directo con el objeto jugador y cambiando el estado de ese objeto en consecuencia de ello, enviando después de eso la lista actualizada al servidor para que procese el resto.

Y aquí entramos en un concepto que son las máquinas de estado finito. Imaginemos por un momente que tenemos todas las transformaciones posibles de Mario en Super Mario World en una tabla…

El estado de Mario antes de coger el objeto y el objeto que acabamos de coger son los parametros de entrada, de ahi podemos sacar una tabla…

MushroomFlowerLeaf
MarioSuper MarioFire MarioCape Mario
Super MarioSuper MarioFire MarioCape Mario
Fire Mario Fire MarioFire MarioCape Mario
Cape MarioCape MarioFire MarioCape Mario

La definición simple es una máquina de estado finito realiza calculos de forma automática sobre unos datos de entrada para producir unos de salida, en el caso de los objetos de lo videojuegos esto se utiliza para representar los cambios de estado de los objetos en el juego cuando colisionan entre si produciendo un resultado que se tiene que encontrar ya en las tablas del objeto o en su defecto tiene que existir un programa relacionado con el objeto que genere unos datos de salida concretos y en los que exista una un cierto grado de nivel de predicción.

¿Pero que ocurre cuando tenemos una escena muy compleja donde objetos que no son el jugador interaccionan entre si pero forman parte del escenario? Estas situaciones suponen que la CPU tenga que calcular por completo esos objetos de manera habitual. ¿Os acordáis de como Asssassin’s Creed Unity esta limitado por CPU en consolas? Pues es precisamente por esto, por tener que calcular el estado de los objetos con lo que no interacciona el jugador, la idea de la patente es simple, que la interacción de esos objetos sea calculada por el servidor en la nube.

Ahora bien, vayamos a la parte del renderizado, al contrario que el Cloud Gaming clásico donde toda la escena e renderizada por completo en el servidor, aqui lo que es el objeto jugador y los objetos con lo que ha tenido interacciones directas son renderizados de manera local pero el resto del escenario es renderizado en el servidor y ambas imagenes son combinadas… ¿Pero como se pueden combinar?

Dentro de la carga de trabajo a la hora de renderizar una escena esta se encuentra más alta durante el rasterizado y el texturizado al depender de la resolución de salida.

Dado que las GPUs son procesadores de flujo cuanto más dato entonces más flujo. Si se procesara la escena al completo en ambos casos y luego se uniera quedaría como un «collage» mal hecho por lo que tiene más sentido que el procesamiento de la geometria del objeto jugador y los objetos con los que interacciona directamente se procesen a nivel local pero no se rastericen a nivel local sino que dicha lista de vertices sea enviada hacía el servidor para que haga el proceso de rasterizado.

Y aqui entramos en uno de los cambios de la siguiente generación, AMD los llamo Primitive Shaders y no pudo incluirlos en Vega pero si que los va a incluir en Navi y realmente son un cambio importante en la etapa geométrica del pipeline.

Pues Nvidia con otra nomenclatura los ha implementado en Turing bajo el nombre de Mesh Shaders pero el concepto es el mismo.

La idea principal es el Primitive Culling que es la eliminación de vertices no visibles o superfluos en la escena. Esto no es nuevo pero no estaba estandarizado y digo que no es nuevo porque muchos juegos en PS3 lo hacían donde el CBEA pre-calculaba la geometria y eliminaba de la lista de vertices a procesar aquellos que seguían ciertas condiciones como…

… son transformados pero que al aplicar las coordenadas de cámara/eye coordinates acaba fuera de escena por estar de espaldas a la cámara.

… se encuentran fuera de la pantalla (Viewport) pero aún así son calculados por el Vertex Shader.

… son lo demasiado pequeños y estan a una distancia lo suficientemente lejana de la cámara como para que el RSX rasterizar y luego texturizar, por lo que es una tontería calcular la geometría de estos.

… a la hora de rasterizarse no llegan a tocar ni un pixel de la escena y por tanto el rasterizador los descartará de entrada.

Pero claro, esto se podía hacer porque los SPE del CBEA funcionan en paralelo, el caso es que Sony junto a AMD intentaron aplicarlo en PS4 o al menos en una futura iteración e incluso hay referencias en una patente de ello.

La idea de Sony era reemplazar los SPE por el pipeline de comptación de la GPU, basicamente haciendo que la GPU calculase la geometria de la escena aplicando el Culling y formando una lista de la geometria antes del rasterizado por lo que en ese caso se comportaría como un Middle Sort, solo que no rasterizaría.

El resultado es que las primitivas que han sido descartadas son descartadas de la lista enviada a la GPU y si, todas y cada una de las primitivas que no han recibido el recorte (culling) son procesadas de nuevo. ¿El problema? Pues que las GPU de la actual generación son Last Sort incluida Xbox One X por lo que no hacen el re-ordenamiento de las primitivas de la escena según su posición antes del rasterizado.

En Nvidia el Middle Sort se hace desde Maxwell pero Nvidia… En AMD tenemos este cambio desde Vega y esta cambio se ve en el Tile Caching de Nvidia que AMD llama DSBR y del que os he comentado tantas veces.

En PS4 Pro a nivel de software se dio una solución parecida pero no es lo mismo dado que la GPU no soporta Middle Soft, es por ello que el ID Buffer que se utiliza para calcular la posición de cada objeto a través de su ID entre dos frames toma el último render target de la GPU.

En cambio la solución que vais a ver es que el calculo de la posición de los objetos en pantalla se hará antes de la fase de rasterizado a través del Middle Sort y se almacenara en un bufer especial llamado Position Buffer.

Pensad en el Position Buffer como las viejas Name Tables que utilizaban los generadores de patrones/sprites donde teniamos una tabla donde colocabamos cada objeto según su posición de pantalla. Una vez hecho esto tenemos dos caminos distintos:

  1. Renderizar de manera local donde los datos de la geometria son enviados al Primitive Assembler de la GPU local.
  2. Enviar los datos a través de la nube para que sea el Primitive Assembler de GPU a nivel servidor la que calcule el resto del resultado.

¿Y que haría el servidor con ambas listas de primitivas? Como las tendría ordenadas por posición de pantalla puede aplicar el Culling con ambas listas y generar una lista común en cuanto a la geometria que rasterizar. La otra gran ventaja es que al ordenar la geometria según su posición «en pantalla» antes del rasterizado (siguen estando en un espacio tridimensional») esto permite subdividir en tiles los espacios y crear listas de geometria por cada un de esos espacios y enviarlas. Esto es clásico de los Tile Renderers pero aqui tenemos que hablar de un tema que AMD ha colocado en Vega 7nm y precisamente en su procesador de comandos que es la virtualización por hardware que permite al proceador de comandos repartir su trabajo entre hasta 16 listas de pantalla distintas. La idea es crear listas de pantalla más pequeñas para así aligerar el transporte de datos y el procesamiento de esto en la nube, luego estos son re-enviados de vuelta ya procesados y para ser ordenados por la GPU cliente.

Dicho de otra manera. estamos ante un caso de Grid Computing que es un tipo de computación en la nube, es decir, estamos delante de lo que Ken Kutaragi tenia como visión para el CBEA a largo plazo y que por limitaciones técnicas no se pudo realizar. No estamos hablando de que una GPU en el servidor no renderiza la escena sino que la escena es subdividida para que varios servidores en paralelo nos la rendericen. La virtualización a nivel de procesador de comandos es muy importante para ello y por eso vimos a Phil Spencer en la conferencia de AMD en el CES.

A nivel de sistema local esto significa que de esto se va a beneficiar solamente el hardware next-gen por el hecho que es necesaria una GPU AMD Navi en adelante o al menos que disponga dicha funcionalidad y paradojicamente el tema del Middle Sort, el ordenamiento de la geometria y la creación de listas de pantalla por cada tile on el estandar de facto en las GPUs para móviles donde todas y cada una de ellas, incluidas las de Nvidia al soportar Tile Caching, pueden realizar lo que os he ido comentando. Es por ello que Microsoft se puede plantear Scarlett Cloud en tablets y smartphones.

Es más, la patente es completamente explicita sobre los tipos de dispositivos que pueden utilizar esto.

Una vez procesada la imagen es enviada directamente al sistema cliente en forma de stream de video desordenado donde los bloques tienen que ser ordenados por la GPU local para mostrarlo en pantalla. Si el sistema tiene la capacidad puede utilizar el Machine Learning para subir de resolución la imagen recibida.

Y con esto termino, espero que la gente haya entendido la entrada y no os haya parecido muy liosa, tenéis los comentarios de esta misma entrada para preguntar y el Discord.