@@ -1313,10 +1313,7 @@ static bool D3D_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
13131313 switch (cmd -> command ) {
13141314 case SDL_RENDERCMD_SETDRAWCOLOR :
13151315 {
1316- /* currently this is sent with each vertex, but if we move to
1317- shaders, we can put this in a uniform here and reduce vertex
1318- buffer bandwidth */
1319- break ;
1316+ break ; // this isn't currently used in this render backend.
13201317 }
13211318
13221319 case SDL_RENDERCMD_SETVIEWPORT :
@@ -1377,43 +1374,74 @@ static bool D3D_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
13771374 break ;
13781375 }
13791376
1380- case SDL_RENDERCMD_DRAW_POINTS :
1381- {
1382- const size_t count = cmd -> data .draw .count ;
1383- const size_t first = cmd -> data .draw .first ;
1384- SetDrawState (data , cmd );
1385- if (vbo ) {
1386- IDirect3DDevice9_DrawPrimitive (data -> device , D3DPT_POINTLIST , (UINT )(first / sizeof (Vertex )), (UINT )count );
1387- } else {
1388- const Vertex * verts = (Vertex * )(((Uint8 * )vertices ) + first );
1389- IDirect3DDevice9_DrawPrimitiveUP (data -> device , D3DPT_POINTLIST , (UINT )count , verts , sizeof (Vertex ));
1390- }
1391- break ;
1392- }
1393-
13941377 case SDL_RENDERCMD_DRAW_LINES :
13951378 {
1396- const size_t count = cmd -> data .draw .count ;
1379+ size_t count = cmd -> data .draw .count ;
13971380 const size_t first = cmd -> data .draw .first ;
1381+ const size_t start = first / sizeof (Vertex );
13981382 const Vertex * verts = (Vertex * )(((Uint8 * )vertices ) + first );
13991383
1400- /* DirectX 9 has the same line rasterization semantics as GDI,
1401- so we need to close the endpoint of the line with a second draw call.
1402- NOLINTNEXTLINE(clang-analyzer-core.NullDereference): FIXME: Can verts truly not be NULL ? */
1403- const bool close_endpoint = ((count == 2 ) || (verts [0 ].x != verts [count - 1 ].x ) || (verts [0 ].y != verts [count - 1 ].y ));
1404-
14051384 SetDrawState (data , cmd );
14061385
1407- if (vbo ) {
1408- IDirect3DDevice9_DrawPrimitive (data -> device , D3DPT_LINESTRIP , (UINT )(first / sizeof (Vertex )), (UINT )(count - 1 ));
1409- if (close_endpoint ) {
1410- IDirect3DDevice9_DrawPrimitive (data -> device , D3DPT_POINTLIST , (UINT )((first / sizeof (Vertex )) + (count - 1 )), 1 );
1386+ // Add the final point in the line
1387+ size_t line_start = 0 ;
1388+ size_t line_end = line_start + count - 1 ;
1389+ if (count == 2 || verts [line_start ].x != verts [line_end ].x || verts [line_start ].y != verts [line_end ].y ) {
1390+ if (vbo ) {
1391+ IDirect3DDevice9_DrawPrimitive (data -> device , D3DPT_POINTLIST , (UINT )(start + line_end ), 1 );
1392+ } else {
1393+ IDirect3DDevice9_DrawPrimitiveUP (data -> device , D3DPT_POINTLIST , 1 , & verts [line_end ], sizeof (Vertex ));
1394+ }
1395+ }
1396+
1397+ if (count > 2 ) {
1398+ // joined lines cannot be grouped
1399+ if (vbo ) {
1400+ IDirect3DDevice9_DrawPrimitive (data -> device , D3DPT_LINESTRIP , (UINT )start , (UINT )(count - 1 ));
1401+ } else {
1402+ IDirect3DDevice9_DrawPrimitiveUP (data -> device , D3DPT_LINESTRIP , (UINT )(count - 1 ), verts , sizeof (Vertex ));
14111403 }
14121404 } else {
1413- IDirect3DDevice9_DrawPrimitiveUP (data -> device , D3DPT_LINESTRIP , (UINT )(count - 1 ), verts , sizeof (Vertex ));
1414- if (close_endpoint ) {
1415- IDirect3DDevice9_DrawPrimitiveUP (data -> device , D3DPT_POINTLIST , 1 , & verts [count - 1 ], sizeof (Vertex ));
1405+ // let's group non joined lines
1406+ SDL_RenderCommand * finalcmd = cmd ;
1407+ SDL_RenderCommand * nextcmd ;
1408+ SDL_BlendMode thisblend = cmd -> data .draw .blend ;
1409+
1410+ for (nextcmd = cmd -> next ; nextcmd ; nextcmd = nextcmd -> next ) {
1411+ const SDL_RenderCommandType nextcmdtype = nextcmd -> command ;
1412+ if (nextcmdtype != SDL_RENDERCMD_DRAW_LINES ) {
1413+ if (nextcmdtype == SDL_RENDERCMD_SETDRAWCOLOR ) {
1414+ // The vertex data has the draw color built in, ignore this
1415+ continue ;
1416+ }
1417+ break ; // can't go any further on this draw call, different render command up next.
1418+ } else if (nextcmd -> data .draw .count != 2 ) {
1419+ break ; // can't go any further on this draw call, those are joined lines
1420+ } else if (nextcmd -> data .draw .blend != thisblend ) {
1421+ break ; // can't go any further on this draw call, different blendmode copy up next.
1422+ } else {
1423+ finalcmd = nextcmd ; // we can combine copy operations here. Mark this one as the furthest okay command.
1424+
1425+ // Add the final point in the line
1426+ line_start = count ;
1427+ line_end = line_start + nextcmd -> data .draw .count - 1 ;
1428+ if (verts [line_start ].x != verts [line_end ].x || verts [line_start ].y != verts [line_end ].y ) {
1429+ if (vbo ) {
1430+ IDirect3DDevice9_DrawPrimitive (data -> device , D3DPT_POINTLIST , (UINT )(start + line_end ), 1 );
1431+ } else {
1432+ IDirect3DDevice9_DrawPrimitiveUP (data -> device , D3DPT_POINTLIST , 1 , & verts [line_end ], sizeof (Vertex ));
1433+ }
1434+ }
1435+ count += nextcmd -> data .draw .count ;
1436+ }
1437+ }
1438+
1439+ if (vbo ) {
1440+ IDirect3DDevice9_DrawPrimitive (data -> device , D3DPT_LINELIST , (UINT )start , (UINT )(count - 1 ));
1441+ } else {
1442+ IDirect3DDevice9_DrawPrimitiveUP (data -> device , D3DPT_LINELIST , (UINT )(count - 1 ), verts , sizeof (Vertex ));
14161443 }
1444+ cmd = finalcmd ; // skip any copy commands we just combined in here.
14171445 }
14181446 break ;
14191447 }
@@ -1427,17 +1455,59 @@ static bool D3D_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
14271455 case SDL_RENDERCMD_COPY_EX : // unused
14281456 break ;
14291457
1458+ case SDL_RENDERCMD_DRAW_POINTS :
14301459 case SDL_RENDERCMD_GEOMETRY :
14311460 {
1432- const size_t count = cmd -> data .draw .count ;
1461+ /* as long as we have the same copy command in a row, with the
1462+ same texture, we can combine them all into a single draw call. */
1463+ SDL_Texture * thistexture = cmd -> data .draw .texture ;
1464+ SDL_BlendMode thisblend = cmd -> data .draw .blend ;
1465+ SDL_ScaleMode thisscalemode = cmd -> data .draw .texture_scale_mode ;
1466+ SDL_TextureAddressMode thisaddressmode_u = cmd -> data .draw .texture_address_mode_u ;
1467+ SDL_TextureAddressMode thisaddressmode_v = cmd -> data .draw .texture_address_mode_v ;
1468+ const SDL_RenderCommandType thiscmdtype = cmd -> command ;
1469+ SDL_RenderCommand * finalcmd = cmd ;
1470+ SDL_RenderCommand * nextcmd ;
1471+ size_t count = cmd -> data .draw .count ;
14331472 const size_t first = cmd -> data .draw .first ;
1473+ const size_t start = first / sizeof (Vertex );
1474+ const Vertex * verts = (Vertex * )(((Uint8 * )vertices ) + first );
1475+ for (nextcmd = cmd -> next ; nextcmd ; nextcmd = nextcmd -> next ) {
1476+ const SDL_RenderCommandType nextcmdtype = nextcmd -> command ;
1477+ if (nextcmdtype != thiscmdtype ) {
1478+ if (nextcmdtype == SDL_RENDERCMD_SETDRAWCOLOR ) {
1479+ // The vertex data has the draw color built in, ignore this
1480+ continue ;
1481+ }
1482+ break ; // can't go any further on this draw call, different render command up next.
1483+ } else if (nextcmd -> data .draw .texture != thistexture ||
1484+ nextcmd -> data .draw .texture_scale_mode != thisscalemode ||
1485+ nextcmd -> data .draw .texture_address_mode_u != thisaddressmode_u ||
1486+ nextcmd -> data .draw .texture_address_mode_v != thisaddressmode_v ||
1487+ nextcmd -> data .draw .blend != thisblend ) {
1488+ break ; // can't go any further on this draw call, different texture/blendmode copy up next.
1489+ } else {
1490+ finalcmd = nextcmd ; // we can combine copy operations here. Mark this one as the furthest okay command.
1491+ count += nextcmd -> data .draw .count ;
1492+ }
1493+ }
1494+
14341495 SetDrawState (data , cmd );
1435- if (vbo ) {
1436- IDirect3DDevice9_DrawPrimitive (data -> device , D3DPT_TRIANGLELIST , (UINT )(first / sizeof (Vertex )), (UINT )count / 3 );
1496+
1497+ if (thiscmdtype == SDL_RENDERCMD_GEOMETRY ) {
1498+ if (vbo ) {
1499+ IDirect3DDevice9_DrawPrimitive (data -> device , D3DPT_TRIANGLELIST , (UINT )start , (UINT )count / 3 );
1500+ } else {
1501+ IDirect3DDevice9_DrawPrimitiveUP (data -> device , D3DPT_TRIANGLELIST , (UINT )count / 3 , verts , sizeof (Vertex ));
1502+ }
14371503 } else {
1438- const Vertex * verts = (Vertex * )(((Uint8 * )vertices ) + first );
1439- IDirect3DDevice9_DrawPrimitiveUP (data -> device , D3DPT_TRIANGLELIST , (UINT )count / 3 , verts , sizeof (Vertex ));
1504+ if (vbo ) {
1505+ IDirect3DDevice9_DrawPrimitive (data -> device , D3DPT_POINTLIST , (UINT )start , (UINT )count );
1506+ } else {
1507+ IDirect3DDevice9_DrawPrimitiveUP (data -> device , D3DPT_POINTLIST , (UINT )count , verts , sizeof (Vertex ));
1508+ }
14401509 }
1510+ cmd = finalcmd ; // skip any copy commands we just combined in here.
14411511 break ;
14421512 }
14431513
0 commit comments