다이렉트X

 
이봐, 아직 directx를 알아낸 사람이 있습니까? DirectCompute가 있습니까?
DirectCompute — Википедия
  • ru.wikipedia.org
Изначально DirectCompute был опубликован в составе DirectX 11, однако позже стал доступен и для DirectX 10 и DirectX 10.1. DirectCompute, впервые появившись в составе DirectX 11, стал одним из важнейших его нововведений, первой технологией в составе DirectX, предоставившей доступ к вычислениям общего назначения на графических процессорах...
 
OpenCL이 있습니다. 그와 함께 모든 것이 훨씬 쉬울 것이라는 의심이 있습니다.)
 

DirectCompute가 필요한 이유:

1) 편리하고 효율적입니다. 결과를 계산하고 즉시 캔버스에 표시할 수 있습니다. OpenCL을 통해 계산을 GPU로 보낸 다음 캔버스에 또 다른 출력 요청을 보내야 하고 pcie를 통해 보내는 것은 오랜 시간이 걸립니다.

2) 다른 API는 작업 및 GPU 벤더에 따라 성능이 크게 다릅니다. 그리고 선택할 것이 많을 것입니다.

3) 언어 선택이 나타납니다. 사람이 hlsl을 알고 있다면 opencl을 배울 필요가 없습니다.

4) 결과의 계산 및 출력을 동일한 언어로 작성할 수 있어 편리합니다.

5) 힙용. 정점이 있고 픽셀이 있고 기하학적인 것도 있지만 계산적인 것은 없습니다.

6) 거의 모든 것이 준비되었습니다. DX는 망쳤습니다. 셰이더를 추가하기만 하면 됩니다. 처음부터 추가할 위치가 아닙니다.

7) 훈련을 위해 그런 일을 하고 싶습니다.

8) 음, 그리고 가장 중요한 것은.

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, программы на которой прекрасно запускаются и на более новых...
 

셰이더 1 2

모든 것의 약간 1 2

 
Aliaksandr Hryshyn :
OpenCL이 있습니다. 그와 함께 모든 것이 훨씬 쉬울 것이라는 의심이 있습니다.)
 
Rorschach :
셰이더 1 2
당신이 포럼에서 약간 착각하고 있다는 의혹이 있습니다.
 
Aliaksandr Hryshyn :
당신이 포럼에서 약간 오해하고 있다는 의혹이 있습니다.

당신이 주제에 약간 오해가 있다는 의혹이 있습니다.

 

최소한의 코드와 성능을 일반 캔버스와 비교하려는 시도(비뚤어진 방식, pcie 버스 추정으로 판명됨)

 #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();
  }
파일:
Shaders.zip  1 kb
 

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

셰이더로 옮겼습니다. 소스 코드가 CPU에서 처음 15초 동안 실행된 다음 GPU 버전이 실행됩니다.

"컴파일하기 전에 Canvas.mqh 파일에서 m_pixels[] 배열을 protected:에서 public:으로 전송해야 합니다."

 #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();
  }
파일:
shaders.zip  1 kb
사유: