From a4f9e5f0d506ee90479cd7c13f356f6dded1b2d7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 17 Apr 2018 10:01:06 +0200 Subject: [PATCH] [hud] Added line renderer --- src/dxvk/hud/dxvk_hud_renderer.cpp | 99 +++++++++++++++++++++++------- src/dxvk/hud/dxvk_hud_renderer.h | 21 +++++++ src/dxvk/hud/shaders/hud_line.frag | 10 +++ src/dxvk/meson.build | 1 + 4 files changed, 109 insertions(+), 22 deletions(-) create mode 100644 src/dxvk/hud/shaders/hud_line.frag diff --git a/src/dxvk/hud/dxvk_hud_renderer.cpp b/src/dxvk/hud/dxvk_hud_renderer.cpp index d5f3a930..18c6da0b 100644 --- a/src/dxvk/hud/dxvk_hud_renderer.cpp +++ b/src/dxvk/hud/dxvk_hud_renderer.cpp @@ -1,5 +1,6 @@ #include "dxvk_hud_renderer.h" +#include #include #include @@ -8,8 +9,10 @@ namespace dxvk::hud { HudRenderer::HudRenderer( const Rc& device, const Rc& context) - : m_vertShader (createVertexShader(device)), + : m_mode (Mode::RenderNone), + m_vertShader (createVertexShader(device)), m_textShader (createTextShader(device)), + m_lineShader (createLineShader(device)), m_fontImage (createFontImage(device)), m_fontView (createFontView(device)), m_fontSampler (createFontSampler(device)), @@ -25,14 +28,8 @@ namespace dxvk::hud { void HudRenderer::beginFrame(const Rc& context) { - context->bindShader(VK_SHADER_STAGE_VERTEX_BIT, m_vertShader); - context->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_textShader); - - DxvkInputAssemblyState iaState; - iaState.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - iaState.primitiveRestart = VK_FALSE; - iaState.patchVertexCount = 0; - context->setInputAssemblyState(iaState); + auto vertexSlice = m_vertexBuffer->allocPhysicalSlice(); + context->invalidateBuffer(m_vertexBuffer, vertexSlice); const std::array ilAttributes = {{ { 0, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(HudVertex, position) }, @@ -57,6 +54,7 @@ namespace dxvk::hud { context->bindResourceSampler(1, m_fontSampler); context->bindResourceView (2, m_fontView, nullptr); + m_mode = Mode::RenderNone; m_vertexIndex = 0; } @@ -67,13 +65,12 @@ namespace dxvk::hud { HudPos pos, HudColor color, const std::string& text) { + this->setRenderMode(context, Mode::RenderText); + const size_t vertexIndex = m_vertexIndex; - auto vertexSlice = m_vertexBuffer->allocPhysicalSlice(); - context->invalidateBuffer(m_vertexBuffer, vertexSlice); - HudVertex* vertexData = reinterpret_cast( - vertexSlice.mapPtr(vertexIndex * sizeof(HudVertex))); + m_vertexBuffer->mapPtr(vertexIndex * sizeof(HudVertex))); const float sizeFactor = size / static_cast(g_hudFont.size); @@ -133,6 +130,60 @@ namespace dxvk::hud { } + void HudRenderer::drawLines( + const Rc& context, + size_t vertexCount, + const HudVertex* vertexData) { + this->setRenderMode(context, Mode::RenderLines); + const size_t vertexIndex = m_vertexIndex; + + HudVertex* dstVertexData = reinterpret_cast( + m_vertexBuffer->mapPtr(vertexIndex * sizeof(HudVertex))); + + for (size_t i = 0; i < vertexCount; i++) + dstVertexData[i] = vertexData[i]; + + context->draw(vertexCount, 1, vertexIndex, 0); + m_vertexIndex += vertexCount; + } + + + void HudRenderer::setRenderMode( + const Rc& context, + Mode mode) { + if (m_mode != mode) { + m_mode = mode; + + switch (mode) { + case Mode::RenderNone: + break; + + case Mode::RenderText: { + context->bindShader(VK_SHADER_STAGE_VERTEX_BIT, m_vertShader); + context->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_textShader); + + DxvkInputAssemblyState iaState; + iaState.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + iaState.primitiveRestart = VK_FALSE; + iaState.patchVertexCount = 0; + context->setInputAssemblyState(iaState); + } break; + + case Mode::RenderLines: { + context->bindShader(VK_SHADER_STAGE_VERTEX_BIT, m_vertShader); + context->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_lineShader); + + DxvkInputAssemblyState iaState; + iaState.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST; + iaState.primitiveRestart = VK_FALSE; + iaState.patchVertexCount = 0; + context->setInputAssemblyState(iaState); + } break; + } + } + } + + Rc HudRenderer::createVertexShader(const Rc& device) { const SpirvCodeBuffer codeBuffer(hud_vert); @@ -141,14 +192,11 @@ namespace dxvk::hud { { 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_IMAGE_VIEW_TYPE_MAX_ENUM }, }}; - // 3 input registers, 2 output registers, tightly packed - const DxvkInterfaceSlots interfaceSlots = { 0x7, 0x3 }; - return new DxvkShader( VK_SHADER_STAGE_VERTEX_BIT, resourceSlots.size(), resourceSlots.data(), - interfaceSlots, + { 0x7, 0x3 }, codeBuffer); } @@ -156,20 +204,27 @@ namespace dxvk::hud { Rc HudRenderer::createTextShader(const Rc& device) { const SpirvCodeBuffer codeBuffer(hud_text); - // One shader resource: Global HUD uniform buffer + // Two shader resources: Font texture and sampler const std::array resourceSlots = {{ { 1, VK_DESCRIPTOR_TYPE_SAMPLER, VK_IMAGE_VIEW_TYPE_MAX_ENUM }, { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_IMAGE_VIEW_TYPE_2D }, }}; - // 2 input registers, 1 output register - const DxvkInterfaceSlots interfaceSlots = { 0x3, 0x1 }; - return new DxvkShader( VK_SHADER_STAGE_FRAGMENT_BIT, resourceSlots.size(), resourceSlots.data(), - interfaceSlots, + { 0x3, 0x1 }, + codeBuffer); + } + + + Rc HudRenderer::createLineShader(const Rc& device) { + const SpirvCodeBuffer codeBuffer(hud_line); + + return new DxvkShader( + VK_SHADER_STAGE_FRAGMENT_BIT, + 0, nullptr, { 0x2, 0x1 }, codeBuffer); } diff --git a/src/dxvk/hud/dxvk_hud_renderer.h b/src/dxvk/hud/dxvk_hud_renderer.h index 4021e2e8..3f9ebe57 100644 --- a/src/dxvk/hud/dxvk_hud_renderer.h +++ b/src/dxvk/hud/dxvk_hud_renderer.h @@ -76,12 +76,26 @@ namespace dxvk::hud { HudColor color, const std::string& text); + void drawLines( + const Rc& context, + size_t vertexCount, + const HudVertex* vertexData); + private: + enum class Mode { + RenderNone, + RenderText, + RenderLines, + }; + std::array m_charMap; + Mode m_mode; + Rc m_vertShader; Rc m_textShader; + Rc m_lineShader; Rc m_fontImage; Rc m_fontView; @@ -90,12 +104,19 @@ namespace dxvk::hud { Rc m_vertexBuffer; size_t m_vertexIndex = 0; + void setRenderMode( + const Rc& context, + Mode mode); + Rc createVertexShader( const Rc& device); Rc createTextShader( const Rc& device); + Rc createLineShader( + const Rc& device); + Rc createFontImage( const Rc& device); diff --git a/src/dxvk/hud/shaders/hud_line.frag b/src/dxvk/hud/shaders/hud_line.frag new file mode 100644 index 00000000..2612605a --- /dev/null +++ b/src/dxvk/hud/shaders/hud_line.frag @@ -0,0 +1,10 @@ +#version 450 + +layout(location = 1) in vec4 v_color; +layout(location = 0) out vec4 o_color; + +void main() { + o_color = vec4( + v_color.rgb * v_color.a, + v_color.a); +} \ No newline at end of file diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index aceb792b..234d1f61 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -12,6 +12,7 @@ dxvk_shaders = files([ 'shaders/dxvk_clear_image3d_u.comp', 'shaders/dxvk_clear_image3d_f.comp', + 'hud/shaders/hud_line.frag', 'hud/shaders/hud_text.frag', 'hud/shaders/hud_vert.vert', ])