I make an editor for own game engine and I used for 2d rendering Direct2D but I wanted to render a directx texture
on window in editor, I didn't find convenient way to convert directx texture to direct2d bitmap. I decided to make own 2d render on directx 11 and I made that but I have poor performance. I knew that my realization to be slower
than direct2d but not in 4 times, how I can make better performance. I made simple profiling, more time to take
call DrawIndexed from directx 11 I don't understand why drawing is so slow. which optimization can I make ?
My 2d render pipeline looks simple. When call draw_rect fucntion function generates vertices and indices for a rect
than a struct which holds vertices and indices is added to na array this from the array draw_primitives takes data and
gets started to render and in the end of frame the array is reseted.
void Render_2D::draw_primitives()
{
if (total_vertex_count == 0) {
return;
}
static u32 privious_total_vertex_count;
static u32 privious_total_index_count;
if (!vertex_buffer || (privious_total_vertex_count != total_vertex_count)) {
privious_total_vertex_count = total_vertex_count;
free_com_object(vertex_buffer);
vertex_buffer = make_vertex_buffer(sizeof(Vertex_XC), total_vertex_count, NULL, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
}
if (!index_buffer || (privious_total_index_count != total_index_count)) {
privious_total_index_count = total_index_count;
free_com_object(index_buffer);
index_buffer = make_index_buffer(total_index_count, NULL, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
}
D3D11_MAPPED_SUBRESOURCE buffer;
ZeroMemory(&buffer, sizeof(D3D11_MAPPED_SUBRESOURCE));
HR(directx11.device_context->Map(vertex_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &buffer));
D3D11_MAPPED_SUBRESOURCE i_buffer;
ZeroMemory(&i_buffer, sizeof(D3D11_MAPPED_SUBRESOURCE));
HR(directx11.device_context->Map(index_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &i_buffer));
Vertex_XC *p1 = (Vertex_XC *)buffer.pData;
u32 *p2 = (u32 *)i_buffer.pData;
Primitive_2D *primitive = NULL;
For(primitives, primitive) {
memcpy((void *)p1, primitive->vertices.items, primitive->vertices.count * sizeof(Vertex_XC));
memcpy((void *)p2, primitive->indices.items, primitive->indices.count * sizeof(u32));
p1 += primitive->vertex_offset;
p2 += primitive->index_offset;
}
directx11.device_context->Unmap(index_buffer, 0);
directx11.device_context->Unmap(vertex_buffer, 0);
Fx_Shader *shader = fx_shader_manager.get_shader("color");
shader->bind("world_view_projection", &render_sys.view_info->orthogonal_matrix);
shader->attach("draw_vertex_on_screen");
D3D11_DEPTH_STENCIL_DESC depth_stencil;
ZeroMemory(&depth_stencil, sizeof(D3D11_DEPTH_STENCIL_DESC));
depth_stencil.DepthEnable = false;
depth_stencil.DepthFunc = D3D11_COMPARISON_ALWAYS;
depth_stencil.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
depth_stencil.StencilEnable = false;
ID3D11DepthStencilState *state = NULL;
directx11.device->CreateDepthStencilState(&depth_stencil, &state);
directx11.device_context->OMSetDepthStencilState(state, 0);
primitive = NULL;
For(primitives, primitive) {
draw_indexed_traingles(vertex_buffer, sizeof(Vertex_XC), "vertex_color", index_buffer, primitive->indices.count, primitive->vertex_offset, primitive->index_offset);
}
directx11.device_context->RSSetState(0);
}