DirectX

 
Olá, alguém já resolveu a questão do DirectCompute, há um DirectCompute lá dentro ?
DirectCompute — Википедия
  • ru.wikipedia.org
Изначально DirectCompute был опубликован в составе DirectX 11, однако позже стал доступен и для DirectX 10 и DirectX 10.1. DirectCompute, впервые появившись в составе DirectX 11, стал одним из важнейших его нововведений, первой технологией в составе DirectX, предоставившей доступ к вычислениям общего назначения на графических процессорах...
 
Existe o OpenCL. Tenho a suspeita de que será muito mais fácil).
 

Em um relance rápido, por que DirectCompute é necessário:

1) É conveniente e eficiente. Você pode calcular e emitir imediatamente o resultado para kanvas. Você precisa enviar o cálculo para a gpu via OpenCL, depois outra solicitação de saída para kanvas, e enviá-la via pcie é longa.

2) As diferentes api diferem muito no desempenho, dependendo da tarefa e do fornecedor de gpu. E haverá muito por onde escolher.

3) Haverá uma escolha de idioma. Se alguém o conhece, ele não terá que aprender opencl.

4) O cálculo e a saída do resultado podem ser escritos em um idioma, o que é conveniente.

5) Para a pilha. Os vértices estão lá, os pixels estão lá, mesmo os geométricos estão lá, mas os computacionais não estão.

6) Quase tudo está pronto para isso. DX está aparafusado, só precisa adicionar um shader, não está adicionando kuda do zero.

7) Eu quero fazer tal coisa para o treinamento.

8) E o mais importante.

GPU Particles с использованием Compute и Geometry шейдеров
GPU Particles с использованием Compute и Geometry шейдеров
  • habr.com
Привет, дорогой читатель! Сегодня мы продолжим изучение графического конвейера, и я расскажу о таких замечательных вещах, как Compute Shader и Geometry Shader на примере создания системы на 1000000+ частиц, которые в свою очередь являются не точками, а квадратами (billboard quads) и имеют свою текстуру. Другими словами, мы выведем 2000000+...
 
DirectX API. OpenGL или DirectX
  • Roman Shatalov - roman@shatalov.su
  • oldshatalov.ghost17.ru
В данном разделе расположены уроки по DirectX 9. Я выбрал именно девятую версию, так как считаю, что полный переход на новые версии Windows произойдёт ещё нескоро. А пока у большинства пользователей установлена операционная система Windows XP, лучше использовать библиотеку DirectX 9, программы на которой прекрасно запускаются и на более новых...
 

Por shader12

Pouco a pouco 1 2

 
Aliaksandr Hryshyn:
Existe o OpenCL. Tenho a suspeita de que será muito mais fácil).
 
Rorschach:
Em shaders 1 2
Há uma suspeita de que o fórum está um pouco errado.
 
Aliaksandr Hryshyn:
Há uma suspeita de que o fórum está um pouco errado.

Há uma suspeita de que você tenha entendido o tópico errado.

 

Código mínimo, além de uma tentativa de comparar o desempenho com um kanvas normal (forma torta, tem pontuação pcie bus)

#include <Canvas\Canvas.mqh>
#resource "/Files/vertex.hlsl" as string VS;
#resource "/Files/pixel.hlsl" as string PS;

struct VSInputVertex
  {
   float             position[4];
   static const DXVertexLayout s_layout[1];
  };
const DXVertexLayout VSInputVertex::s_layout[1]=
  {
     {"POSITION", 0, DX_FORMAT_R32G32B32A32_FLOAT }
  };

void OnStart()
  {
   int size=500;
   CCanvas cc;
   cc.CreateBitmapLabel("11",100,100,size,size);
   cc.Erase(ColorToARGB(clrGreen));
   cc.Update();
   Sleep(1000);
   VSInputVertex vertex[];
   ArrayResize(vertex,size*size);
   for(int y=0;y<size;y++)
     {for(int x=0;x<size;x++)
        {vertex[y*size+x].position[0]=2.f*(x+1)/size-1.f;
         vertex[y*size+x].position[1]=2.f*(y+1)/size-1.f;
         vertex[y*size+x].position[2]=0.5;
         vertex[y*size+x].position[3]=1.0;
        }
     }
   int hc=DXContextCreate(size,size);
   int hbv=DXBufferCreate(hc,DX_BUFFER_VERTEX,vertex);
   string s="";
   int hsv=DXShaderCreate(hc,DX_SHADER_VERTEX,VS,"main",s);
   int hsp=DXShaderCreate(hc,DX_SHADER_PIXEL ,PS,"main",s);
   DXShaderSetLayout(hsv,VSInputVertex::s_layout);
   DXPrimiveTopologySet(hc,DX_PRIMITIVE_TOPOLOGY_POINTLIST);
   DXBufferSet(hc,hbv);
   DXShaderSet(hc,hsv);
   DXShaderSet(hc,hsp);
   DXContextClearDepth(hc);
   DXDraw(hc);
   uint image[];
   ulong t1=GetMicrosecondCount();
   DXContextGetColors(hc,image);
   ulong t2=GetMicrosecondCount();
   for(int y=0;y<size;y++)
      for(int x=0;x<size;x++)
         cc.PixelSet(x,y,image[y*size+x]);
   ulong t3=GetMicrosecondCount();
   cc.Update();
   Print(t2-t1," ",t3-t2);
   Sleep(1000);
   DXRelease(hsp);
   DXRelease(hsv);
   DXRelease(hbv);
   DXRelease(hc);
   cc.Destroy();
  }
Arquivos anexados:
Shaders.zip  1 kb
 

https://www.mql5.com/ru/forum/227736

Transferido para shader. Os primeiros 15 segundos rodam o código fonte na cpu, depois roda a versão gpu.

"Você precisa mover o array m_pixels[] em arquivo Canvas.mqh de protegido: para público:"

#include <Canvas\Canvas.mqh>
#resource "/Files/vertex.hlsl" as string VS;
#resource "/Files/pixel.hlsl" as string PS;

struct VSInputVertex
  {float             position[4];
   static const DXVertexLayout s_layout[1];
  };
const DXVertexLayout VSInputVertex::s_layout[1]={{"POSITION", 0, DX_FORMAT_R32G32B32A32_FLOAT}};

struct PSInputBuffer
  {float             resolution[2];
   float             time;
   float             dummy;
  };

void OnStart()
  {CCanvas C;
   int Width=(ushort)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);  // получаем Ширину окна
   int Height=(ushort)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS); // получаем Высоту окна
   if(!C.CreateBitmapLabel(0,0,"CanvasExamlple",0,0,Width,Height,COLOR_FORMAT_XRGB_NOALPHA)) // создаем канвас размером текущего окна
   Print("Error creating canvas: ",GetLastError()); 
   //---CPU---
   uint i=0,j=100000;
   int size=Width*Height;
   uchar h[25600];
   for (int w=0;w<25600;w++) 
   h[w]= uchar(128+128*sin(double(w)/256));//создаем массив для ускорения работы
   double X1=0,Y1=0,X2=0,Y2=0;
   uint t0=GetTickCount();
   uint t1=0;
   while(!IsStopped())
     {int pos=int(i%size);
      if(pos==0)
        {C.TextOut(100,100,"CPU FPS: "+DoubleToString(1000./(GetTickCount()-t1),2),clrWhite);
         t1=GetTickCount();
         C.Update();
         if(t1-t0>15000) break;
         //Sleep(30);
         X1= Width-(sin((double)j/100)*(double)Width);
         Y1= Height-(cos((double)j/140)*(double)Height);
         X2= Width+(cos((double)j/80)*(double)Width);
         Y2= Height+(sin((double)j/20)*(double)Height);
         j++;
        }
      int X=pos%Width;
      int Y=int(pos/Width);
      double d= ((X1-X)*(X1-X)+(Y1-Y)*(Y1-Y))/(((X1-X)*(X1-X)+(Y1-Y)*(Y1-Y))+((X2-X)*(X2-X)+(Y2-Y)*(Y2-Y)));
      C.m_pixels[pos]=XRGB(h[int(d*11520)],h[int(d*17920)],h[int(d*6400)]);
      i++;
     }
   //---GPU---
   VSInputVertex vertex[]= {{{-1,-1,0.5,1.0}},{{-1,1,0.5,1.0}},{{1,1,0.5,1.0}},{{1,-1,0.5,1.0}}};
   int hc=DXContextCreate(Width,Height);
   int hbv=DXBufferCreate(hc,DX_BUFFER_VERTEX,vertex);
   uint index[]={0,1,2, 2,3,0};
   int hbi=DXBufferCreate(hc,DX_BUFFER_INDEX ,index );
   string s="";
   int hsv=DXShaderCreate(hc,DX_SHADER_VERTEX,VS,"main",s);
   int hsp=DXShaderCreate(hc,DX_SHADER_PIXEL ,PS,"main",s);
   int hi[1];
   hi[0]=DXInputCreate(hc,sizeof(PSInputBuffer));
   DXShaderInputsSet(hsp,hi);
   DXShaderSetLayout(hsv,VSInputVertex::s_layout);
   DXPrimiveTopologySet(hc,DX_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
   DXBufferSet(hc,hbv);
   DXBufferSet(hc,hbi);
   DXShaderSet(hc,hsv);
   DXShaderSet(hc,hsp);
   
   PSInputBuffer frame_data;
   frame_data.resolution[0]=(float)Width;
   frame_data.resolution[1]=(float)Height;
   for(uint n=100000;!IsStopped();n++)
     {DXContextClearDepth(hc);
      frame_data.time=(float)n;
      DXInputSet(hi[0],frame_data);
      DXDrawIndexed(hc);
      DXContextGetColors(hc,C.m_pixels);
      C.TextOut(100,100,"GPU FPS: "+DoubleToString(1000./(GetTickCount()-t1),2),clrWhite);
      C.Update();
      t1=GetTickCount();
     }
   
   DXRelease(hi[0]);
   DXRelease(hsp);
   DXRelease(hsv);
   DXRelease(hbv);
   DXRelease(hbi);
   DXRelease(hc);
   C.Destroy();
  }
Arquivos anexados:
shaders.zip  1 kb
Razão: