mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
[hud] Optimize HUD rendering
Saves some bandwidth by using more compact vertex formats, and by using push constants for text colors instead of a vertex attribute.
This commit is contained in:
parent
02768182f1
commit
9355580c4f
@ -77,7 +77,7 @@ namespace dxvk::hud {
|
|||||||
const Rc<DxvkContext>& context,
|
const Rc<DxvkContext>& context,
|
||||||
HudRenderer& renderer,
|
HudRenderer& renderer,
|
||||||
HudPos position) {
|
HudPos position) {
|
||||||
std::array<HudVertex, NumDataPoints * 2> vData;
|
std::array<HudLineVertex, NumDataPoints * 2> vData;
|
||||||
|
|
||||||
// 60 FPS = optimal, 10 FPS = worst
|
// 60 FPS = optimal, 10 FPS = worst
|
||||||
const float targetUs = 16'666.6f;
|
const float targetUs = 16'666.6f;
|
||||||
@ -100,8 +100,10 @@ namespace dxvk::hud {
|
|||||||
float g = std::min(std::max( 3.0f - us / targetUs, 0.0f), 1.0f);
|
float g = std::min(std::max( 3.0f - us / targetUs, 0.0f), 1.0f);
|
||||||
float l = std::sqrt(r * r + g * g);
|
float l = std::sqrt(r * r + g * g);
|
||||||
|
|
||||||
HudTexCoord tc = { 0u, 0u };
|
HudNormColor color = {
|
||||||
HudColor color = { r / l, g / l, 0.0f, 1.0f };
|
uint8_t(255.0f * (r / l)),
|
||||||
|
uint8_t(255.0f * (g / l)),
|
||||||
|
uint8_t(0), uint8_t(255) };
|
||||||
|
|
||||||
float x = position.x + float(i);
|
float x = position.x + float(i);
|
||||||
float y = position.y + 24.0f;
|
float y = position.y + 24.0f;
|
||||||
@ -110,8 +112,8 @@ namespace dxvk::hud {
|
|||||||
/ std::log2((maxUs - minUs) / targetUs);
|
/ std::log2((maxUs - minUs) / targetUs);
|
||||||
float h = std::min(std::max(40.0f * hVal, 2.0f), 40.0f);
|
float h = std::min(std::max(40.0f * hVal, 2.0f), 40.0f);
|
||||||
|
|
||||||
vData[2 * i + 0] = HudVertex { { x, y }, tc, color };
|
vData[2 * i + 0] = HudLineVertex { { x, y }, color };
|
||||||
vData[2 * i + 1] = HudVertex { { x, y - h }, tc, color };
|
vData[2 * i + 1] = HudLineVertex { { x, y - h }, color };
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.drawLines(context, vData.size(), vData.data());
|
renderer.drawLines(context, vData.size(), vData.data());
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
#include "dxvk_hud_renderer.h"
|
#include "dxvk_hud_renderer.h"
|
||||||
|
|
||||||
#include <hud_line.h>
|
#include <hud_line_frag.h>
|
||||||
#include <hud_text.h>
|
#include <hud_line_vert.h>
|
||||||
#include <hud_vert.h>
|
|
||||||
|
#include <hud_text_frag.h>
|
||||||
|
#include <hud_text_vert.h>
|
||||||
|
|
||||||
namespace dxvk::hud {
|
namespace dxvk::hud {
|
||||||
|
|
||||||
HudRenderer::HudRenderer(const Rc<DxvkDevice>& device)
|
HudRenderer::HudRenderer(const Rc<DxvkDevice>& device)
|
||||||
: m_mode (Mode::RenderNone),
|
: m_mode (Mode::RenderNone),
|
||||||
m_surfaceSize { 0, 0 },
|
m_surfaceSize { 0, 0 },
|
||||||
m_vertShader (createVertexShader(device)),
|
m_textShaders (createTextShaders(device)),
|
||||||
m_textShader (createTextShader(device)),
|
m_lineShaders (createLineShaders(device)),
|
||||||
m_lineShader (createLineShader(device)),
|
|
||||||
m_fontImage (createFontImage(device)),
|
m_fontImage (createFontImage(device)),
|
||||||
m_fontView (createFontView(device)),
|
m_fontView (createFontView(device)),
|
||||||
m_fontSampler (createFontSampler(device)),
|
m_fontSampler (createFontSampler(device)),
|
||||||
@ -30,32 +31,11 @@ namespace dxvk::hud {
|
|||||||
auto vertexSlice = m_vertexBuffer->allocSlice();
|
auto vertexSlice = m_vertexBuffer->allocSlice();
|
||||||
context->invalidateBuffer(m_vertexBuffer, vertexSlice);
|
context->invalidateBuffer(m_vertexBuffer, vertexSlice);
|
||||||
|
|
||||||
const std::array<DxvkVertexAttribute, 3> ilAttributes = {{
|
|
||||||
{ 0, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(HudVertex, position) },
|
|
||||||
{ 1, 0, VK_FORMAT_R32G32_UINT, offsetof(HudVertex, texcoord) },
|
|
||||||
{ 2, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(HudVertex, color) },
|
|
||||||
}};
|
|
||||||
|
|
||||||
const std::array<DxvkVertexBinding, 1> ilBindings = {{
|
|
||||||
{ 0, VK_VERTEX_INPUT_RATE_VERTEX },
|
|
||||||
}};
|
|
||||||
|
|
||||||
context->setInputLayout(
|
|
||||||
ilAttributes.size(),
|
|
||||||
ilAttributes.data(),
|
|
||||||
ilBindings.size(),
|
|
||||||
ilBindings.data());
|
|
||||||
|
|
||||||
context->bindVertexBuffer(0,
|
|
||||||
DxvkBufferSlice(m_vertexBuffer),
|
|
||||||
sizeof(HudVertex));
|
|
||||||
|
|
||||||
context->bindResourceSampler(1, m_fontSampler);
|
context->bindResourceSampler(1, m_fontSampler);
|
||||||
context->bindResourceView (1, m_fontView, nullptr);
|
context->bindResourceView (1, m_fontView, nullptr);
|
||||||
|
|
||||||
m_mode = Mode::RenderNone;
|
m_mode = Mode::RenderNone;
|
||||||
m_surfaceSize = surfaceSize;
|
m_surfaceSize = surfaceSize;
|
||||||
m_vertexIndex = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -65,12 +45,19 @@ namespace dxvk::hud {
|
|||||||
HudPos pos,
|
HudPos pos,
|
||||||
HudColor color,
|
HudColor color,
|
||||||
const std::string& text) {
|
const std::string& text) {
|
||||||
this->setRenderMode(context, Mode::RenderText);
|
beginTextRendering(context);
|
||||||
|
|
||||||
|
uint32_t vertexCount = 6 * text.size();
|
||||||
|
|
||||||
|
auto vertexSlice = allocVertexBuffer(context,
|
||||||
|
vertexCount * sizeof(HudTextVertex));
|
||||||
|
|
||||||
const size_t vertexIndex = m_vertexIndex;
|
context->bindVertexBuffer(0, vertexSlice, sizeof(HudTextVertex));
|
||||||
|
context->pushConstants(0, sizeof(color), &color);
|
||||||
HudVertex* vertexData = reinterpret_cast<HudVertex*>(
|
context->draw(vertexCount, 1, 0, 0);
|
||||||
m_vertexBuffer->mapPtr(vertexIndex * sizeof(HudVertex)));
|
|
||||||
|
auto vertexData = reinterpret_cast<HudTextVertex*>(
|
||||||
|
vertexSlice.getSliceHandle().mapPtr);
|
||||||
|
|
||||||
const float sizeFactor = size / static_cast<float>(g_hudFont.size);
|
const float sizeFactor = size / static_cast<float>(g_hudFont.size);
|
||||||
|
|
||||||
@ -99,132 +86,183 @@ namespace dxvk::hud {
|
|||||||
|
|
||||||
vertexData[6 * i + 0].position = { posTl.x, posTl.y };
|
vertexData[6 * i + 0].position = { posTl.x, posTl.y };
|
||||||
vertexData[6 * i + 0].texcoord = { texTl.u, texTl.v };
|
vertexData[6 * i + 0].texcoord = { texTl.u, texTl.v };
|
||||||
vertexData[6 * i + 0].color = color;
|
|
||||||
|
|
||||||
vertexData[6 * i + 1].position = { posBr.x, posTl.y };
|
vertexData[6 * i + 1].position = { posBr.x, posTl.y };
|
||||||
vertexData[6 * i + 1].texcoord = { texBr.u, texTl.v };
|
vertexData[6 * i + 1].texcoord = { texBr.u, texTl.v };
|
||||||
vertexData[6 * i + 1].color = color;
|
|
||||||
|
|
||||||
vertexData[6 * i + 2].position = { posTl.x, posBr.y };
|
vertexData[6 * i + 2].position = { posTl.x, posBr.y };
|
||||||
vertexData[6 * i + 2].texcoord = { texTl.u, texBr.v };
|
vertexData[6 * i + 2].texcoord = { texTl.u, texBr.v };
|
||||||
vertexData[6 * i + 2].color = color;
|
|
||||||
|
|
||||||
vertexData[6 * i + 3].position = { posBr.x, posBr.y };
|
vertexData[6 * i + 3].position = { posBr.x, posBr.y };
|
||||||
vertexData[6 * i + 3].texcoord = { texBr.u, texBr.v };
|
vertexData[6 * i + 3].texcoord = { texBr.u, texBr.v };
|
||||||
vertexData[6 * i + 3].color = color;
|
|
||||||
|
|
||||||
vertexData[6 * i + 4].position = { posTl.x, posBr.y };
|
vertexData[6 * i + 4].position = { posTl.x, posBr.y };
|
||||||
vertexData[6 * i + 4].texcoord = { texTl.u, texBr.v };
|
vertexData[6 * i + 4].texcoord = { texTl.u, texBr.v };
|
||||||
vertexData[6 * i + 4].color = color;
|
|
||||||
|
|
||||||
vertexData[6 * i + 5].position = { posBr.x, posTl.y };
|
vertexData[6 * i + 5].position = { posBr.x, posTl.y };
|
||||||
vertexData[6 * i + 5].texcoord = { texBr.u, texTl.v };
|
vertexData[6 * i + 5].texcoord = { texBr.u, texTl.v };
|
||||||
vertexData[6 * i + 5].color = color;
|
|
||||||
|
|
||||||
pos.x += sizeFactor * static_cast<float>(g_hudFont.advance);
|
pos.x += sizeFactor * static_cast<float>(g_hudFont.advance);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t vertexCount = 6 * text.size();
|
|
||||||
context->draw(vertexCount, 1, vertexIndex, 0);
|
|
||||||
m_vertexIndex += vertexCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void HudRenderer::drawLines(
|
void HudRenderer::drawLines(
|
||||||
const Rc<DxvkContext>& context,
|
const Rc<DxvkContext>& context,
|
||||||
size_t vertexCount,
|
size_t vertexCount,
|
||||||
const HudVertex* vertexData) {
|
const HudLineVertex* vertexData) {
|
||||||
this->setRenderMode(context, Mode::RenderLines);
|
beginLineRendering(context);
|
||||||
const size_t vertexIndex = m_vertexIndex;
|
|
||||||
|
auto vertexSlice = allocVertexBuffer(context,
|
||||||
|
vertexCount * sizeof(HudLineVertex));
|
||||||
|
|
||||||
HudVertex* dstVertexData = reinterpret_cast<HudVertex*>(
|
context->bindVertexBuffer(0, vertexSlice, sizeof(HudLineVertex));
|
||||||
m_vertexBuffer->mapPtr(vertexIndex * sizeof(HudVertex)));
|
context->draw(vertexCount, 1, 0, 0);
|
||||||
|
|
||||||
|
auto dstVertexData = reinterpret_cast<HudLineVertex*>(
|
||||||
|
vertexSlice.getSliceHandle().mapPtr);
|
||||||
|
|
||||||
for (size_t i = 0; i < vertexCount; i++)
|
for (size_t i = 0; i < vertexCount; i++)
|
||||||
dstVertexData[i] = vertexData[i];
|
dstVertexData[i] = vertexData[i];
|
||||||
|
|
||||||
context->draw(vertexCount, 1, vertexIndex, 0);
|
|
||||||
m_vertexIndex += vertexCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void HudRenderer::setRenderMode(
|
DxvkBufferSlice HudRenderer::allocVertexBuffer(
|
||||||
const Rc<DxvkContext>& context,
|
const Rc<DxvkContext>& context,
|
||||||
Mode mode) {
|
VkDeviceSize dataSize) {
|
||||||
if (m_mode != mode) {
|
dataSize = align(dataSize, 64);
|
||||||
m_mode = mode;
|
|
||||||
|
if (m_vertexOffset + dataSize > m_vertexBuffer->info().size) {
|
||||||
switch (mode) {
|
context->invalidateBuffer(m_vertexBuffer, m_vertexBuffer->allocSlice());
|
||||||
case Mode::RenderNone:
|
m_vertexOffset = 0;
|
||||||
break;
|
}
|
||||||
|
|
||||||
case Mode::RenderText: {
|
DxvkBufferSlice slice(m_vertexBuffer, m_vertexOffset, dataSize);
|
||||||
context->bindShader(VK_SHADER_STAGE_VERTEX_BIT, m_vertShader);
|
m_vertexOffset += dataSize;
|
||||||
context->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_textShader);
|
return slice;
|
||||||
|
}
|
||||||
DxvkInputAssemblyState iaState;
|
|
||||||
iaState.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
|
||||||
iaState.primitiveRestart = VK_FALSE;
|
void HudRenderer::beginTextRendering(
|
||||||
iaState.patchVertexCount = 0;
|
const Rc<DxvkContext>& context) {
|
||||||
context->setInputAssemblyState(iaState);
|
if (m_mode != Mode::RenderText) {
|
||||||
} break;
|
m_mode = Mode::RenderText;
|
||||||
|
|
||||||
case Mode::RenderLines: {
|
context->bindShader(VK_SHADER_STAGE_VERTEX_BIT, m_textShaders.vert);
|
||||||
context->bindShader(VK_SHADER_STAGE_VERTEX_BIT, m_vertShader);
|
context->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_textShaders.frag);
|
||||||
context->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_lineShader);
|
|
||||||
|
static const DxvkInputAssemblyState iaState = {
|
||||||
DxvkInputAssemblyState iaState;
|
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
|
||||||
iaState.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
|
VK_FALSE, 0 };
|
||||||
iaState.primitiveRestart = VK_FALSE;
|
|
||||||
iaState.patchVertexCount = 0;
|
static const std::array<DxvkVertexAttribute, 2> ilAttributes = {{
|
||||||
context->setInputAssemblyState(iaState);
|
{ 0, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(HudTextVertex, position) },
|
||||||
} break;
|
{ 1, 0, VK_FORMAT_R32G32_UINT, offsetof(HudTextVertex, texcoord) },
|
||||||
}
|
}};
|
||||||
|
|
||||||
|
static const std::array<DxvkVertexBinding, 1> ilBindings = {{
|
||||||
|
{ 0, VK_VERTEX_INPUT_RATE_VERTEX },
|
||||||
|
}};
|
||||||
|
|
||||||
|
context->setInputAssemblyState(iaState);
|
||||||
|
context->setInputLayout(
|
||||||
|
ilAttributes.size(),
|
||||||
|
ilAttributes.data(),
|
||||||
|
ilBindings.size(),
|
||||||
|
ilBindings.data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void HudRenderer::beginLineRendering(
|
||||||
|
const Rc<DxvkContext>& context) {
|
||||||
|
if (m_mode != Mode::RenderLines) {
|
||||||
|
m_mode = Mode::RenderLines;
|
||||||
|
|
||||||
|
context->bindShader(VK_SHADER_STAGE_VERTEX_BIT, m_lineShaders.vert);
|
||||||
|
context->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_lineShaders.frag);
|
||||||
|
|
||||||
|
static const DxvkInputAssemblyState iaState = {
|
||||||
|
VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
|
||||||
|
VK_FALSE, 0 };
|
||||||
|
|
||||||
|
static const std::array<DxvkVertexAttribute, 2> ilAttributes = {{
|
||||||
|
{ 0, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(HudLineVertex, position) },
|
||||||
|
{ 1, 0, VK_FORMAT_R8G8B8A8_UNORM, offsetof(HudLineVertex, color) },
|
||||||
|
}};
|
||||||
|
|
||||||
|
static const std::array<DxvkVertexBinding, 1> ilBindings = {{
|
||||||
|
{ 0, VK_VERTEX_INPUT_RATE_VERTEX },
|
||||||
|
}};
|
||||||
|
|
||||||
|
context->setInputAssemblyState(iaState);
|
||||||
|
context->setInputLayout(
|
||||||
|
ilAttributes.size(),
|
||||||
|
ilAttributes.data(),
|
||||||
|
ilBindings.size(),
|
||||||
|
ilBindings.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkShader> HudRenderer::createVertexShader(const Rc<DxvkDevice>& device) {
|
HudRenderer::ShaderPair HudRenderer::createTextShaders(const Rc<DxvkDevice>& device) {
|
||||||
const SpirvCodeBuffer codeBuffer(hud_vert);
|
ShaderPair result;
|
||||||
|
|
||||||
|
const SpirvCodeBuffer vsCode(hud_text_vert);
|
||||||
|
const SpirvCodeBuffer fsCode(hud_text_frag);
|
||||||
|
|
||||||
// One shader resource: Global HUD uniform buffer
|
// One shader resource: Global HUD uniform buffer
|
||||||
const std::array<DxvkResourceSlot, 1> resourceSlots = {{
|
const std::array<DxvkResourceSlot, 1> vsResources = {{
|
||||||
{ 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_IMAGE_VIEW_TYPE_MAX_ENUM },
|
{ 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_IMAGE_VIEW_TYPE_MAX_ENUM },
|
||||||
}};
|
}};
|
||||||
|
|
||||||
return device->createShader(
|
|
||||||
VK_SHADER_STAGE_VERTEX_BIT,
|
|
||||||
resourceSlots.size(),
|
|
||||||
resourceSlots.data(),
|
|
||||||
{ 0x7, 0x3 },
|
|
||||||
codeBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkShader> HudRenderer::createTextShader(const Rc<DxvkDevice>& device) {
|
|
||||||
const SpirvCodeBuffer codeBuffer(hud_text);
|
|
||||||
|
|
||||||
// Two shader resources: Font texture and sampler
|
// Two shader resources: Font texture and sampler
|
||||||
const std::array<DxvkResourceSlot, 1> resourceSlots = {{
|
const std::array<DxvkResourceSlot, 1> fsResources = {{
|
||||||
{ 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_IMAGE_VIEW_TYPE_2D },
|
{ 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_IMAGE_VIEW_TYPE_2D },
|
||||||
}};
|
}};
|
||||||
|
|
||||||
return device->createShader(
|
result.vert = device->createShader(
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
VK_SHADER_STAGE_VERTEX_BIT,
|
||||||
resourceSlots.size(),
|
vsResources.size(),
|
||||||
resourceSlots.data(),
|
vsResources.data(),
|
||||||
{ 0x3, 0x1 },
|
{ 0x3, 0x1 },
|
||||||
codeBuffer);
|
vsCode);
|
||||||
|
|
||||||
|
result.frag = device->createShader(
|
||||||
|
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||||
|
fsResources.size(),
|
||||||
|
fsResources.data(),
|
||||||
|
{ 0x1, 0x1, 0, sizeof(HudColor) },
|
||||||
|
fsCode);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkShader> HudRenderer::createLineShader(const Rc<DxvkDevice>& device) {
|
HudRenderer::ShaderPair HudRenderer::createLineShaders(const Rc<DxvkDevice>& device) {
|
||||||
const SpirvCodeBuffer codeBuffer(hud_line);
|
ShaderPair result;
|
||||||
|
|
||||||
|
const SpirvCodeBuffer vsCode(hud_line_vert);
|
||||||
|
const SpirvCodeBuffer fsCode(hud_line_frag);
|
||||||
|
|
||||||
return device->createShader(
|
// One shader resource: Global HUD uniform buffer
|
||||||
|
const std::array<DxvkResourceSlot, 1> vsResources = {{
|
||||||
|
{ 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_IMAGE_VIEW_TYPE_MAX_ENUM },
|
||||||
|
}};
|
||||||
|
|
||||||
|
result.vert = device->createShader(
|
||||||
|
VK_SHADER_STAGE_VERTEX_BIT,
|
||||||
|
vsResources.size(),
|
||||||
|
vsResources.data(),
|
||||||
|
{ 0x3, 0x1 },
|
||||||
|
vsCode);
|
||||||
|
|
||||||
|
result.frag = device->createShader(
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||||
0, nullptr, { 0x2, 0x1 },
|
0, nullptr, { 0x1, 0x1 },
|
||||||
codeBuffer);
|
fsCode);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -289,7 +327,7 @@ namespace dxvk::hud {
|
|||||||
|
|
||||||
Rc<DxvkBuffer> HudRenderer::createVertexBuffer(const Rc<DxvkDevice>& device) {
|
Rc<DxvkBuffer> HudRenderer::createVertexBuffer(const Rc<DxvkDevice>& device) {
|
||||||
DxvkBufferCreateInfo info;
|
DxvkBufferCreateInfo info;
|
||||||
info.size = MaxVertexCount * sizeof(HudVertex);
|
info.size = 1 << 16;
|
||||||
info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
||||||
info.stages = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
|
info.stages = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
|
||||||
info.access = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
|
info.access = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
|
||||||
|
@ -40,14 +40,32 @@ namespace dxvk::hud {
|
|||||||
float b;
|
float b;
|
||||||
float a;
|
float a;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Normalized color
|
||||||
|
* SRGB color with alpha channel.
|
||||||
|
*/
|
||||||
|
struct HudNormColor {
|
||||||
|
uint8_t r;
|
||||||
|
uint8_t g;
|
||||||
|
uint8_t b;
|
||||||
|
uint8_t a;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Vertex
|
* \brief Text vertex and texture coordinates
|
||||||
*/
|
*/
|
||||||
struct HudVertex {
|
struct HudTextVertex {
|
||||||
HudPos position;
|
HudPos position;
|
||||||
HudTexCoord texcoord;
|
HudTexCoord texcoord;
|
||||||
HudColor color;
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Line vertex and color
|
||||||
|
*/
|
||||||
|
struct HudLineVertex {
|
||||||
|
HudPos position;
|
||||||
|
HudNormColor color;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,7 +75,7 @@ namespace dxvk::hud {
|
|||||||
* display performance and driver information.
|
* display performance and driver information.
|
||||||
*/
|
*/
|
||||||
class HudRenderer {
|
class HudRenderer {
|
||||||
constexpr static VkDeviceSize MaxVertexCount = 1 << 16;
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
HudRenderer(
|
HudRenderer(
|
||||||
@ -79,7 +97,7 @@ namespace dxvk::hud {
|
|||||||
void drawLines(
|
void drawLines(
|
||||||
const Rc<DxvkContext>& context,
|
const Rc<DxvkContext>& context,
|
||||||
size_t vertexCount,
|
size_t vertexCount,
|
||||||
const HudVertex* vertexData);
|
const HudLineVertex* vertexData);
|
||||||
|
|
||||||
VkExtent2D surfaceSize() const {
|
VkExtent2D surfaceSize() const {
|
||||||
return m_surfaceSize;
|
return m_surfaceSize;
|
||||||
@ -92,34 +110,41 @@ namespace dxvk::hud {
|
|||||||
RenderText,
|
RenderText,
|
||||||
RenderLines,
|
RenderLines,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ShaderPair {
|
||||||
|
Rc<DxvkShader> vert;
|
||||||
|
Rc<DxvkShader> frag;
|
||||||
|
};
|
||||||
|
|
||||||
std::array<uint8_t, 256> m_charMap;
|
std::array<uint8_t, 256> m_charMap;
|
||||||
|
|
||||||
Mode m_mode;
|
Mode m_mode;
|
||||||
VkExtent2D m_surfaceSize;
|
VkExtent2D m_surfaceSize;
|
||||||
|
|
||||||
Rc<DxvkShader> m_vertShader;
|
ShaderPair m_textShaders;
|
||||||
Rc<DxvkShader> m_textShader;
|
ShaderPair m_lineShaders;
|
||||||
Rc<DxvkShader> m_lineShader;
|
|
||||||
|
|
||||||
Rc<DxvkImage> m_fontImage;
|
Rc<DxvkImage> m_fontImage;
|
||||||
Rc<DxvkImageView> m_fontView;
|
Rc<DxvkImageView> m_fontView;
|
||||||
Rc<DxvkSampler> m_fontSampler;
|
Rc<DxvkSampler> m_fontSampler;
|
||||||
|
|
||||||
Rc<DxvkBuffer> m_vertexBuffer;
|
Rc<DxvkBuffer> m_vertexBuffer;
|
||||||
size_t m_vertexIndex = 0;
|
VkDeviceSize m_vertexOffset = 0;
|
||||||
|
|
||||||
void setRenderMode(
|
DxvkBufferSlice allocVertexBuffer(
|
||||||
const Rc<DxvkContext>& context,
|
const Rc<DxvkContext>& context,
|
||||||
Mode mode);
|
VkDeviceSize dataSize);
|
||||||
|
|
||||||
|
void beginTextRendering(
|
||||||
|
const Rc<DxvkContext>& context);
|
||||||
|
|
||||||
Rc<DxvkShader> createVertexShader(
|
void beginLineRendering(
|
||||||
|
const Rc<DxvkContext>& context);
|
||||||
|
|
||||||
|
ShaderPair createTextShaders(
|
||||||
const Rc<DxvkDevice>& device);
|
const Rc<DxvkDevice>& device);
|
||||||
|
|
||||||
Rc<DxvkShader> createTextShader(
|
ShaderPair createLineShaders(
|
||||||
const Rc<DxvkDevice>& device);
|
|
||||||
|
|
||||||
Rc<DxvkShader> createLineShader(
|
|
||||||
const Rc<DxvkDevice>& device);
|
const Rc<DxvkDevice>& device);
|
||||||
|
|
||||||
Rc<DxvkImage> createFontImage(
|
Rc<DxvkImage> createFontImage(
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
layout(location = 1) in vec4 v_color;
|
layout(location = 0) in vec4 v_color;
|
||||||
layout(location = 0) out vec4 o_color;
|
layout(location = 0) out vec4 o_color;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
18
src/dxvk/hud/shaders/hud_line_vert.vert
Normal file
18
src/dxvk/hud/shaders/hud_line_vert.vert
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(set = 0, binding = 0, std140)
|
||||||
|
uniform u_hud {
|
||||||
|
uvec2 size;
|
||||||
|
} g_hud;
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 v_position;
|
||||||
|
layout(location = 1) in vec4 v_color;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 o_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
o_color = v_color;
|
||||||
|
|
||||||
|
vec2 pos = 2.0f * (v_position / vec2(g_hud.size)) - 1.0f;
|
||||||
|
gl_Position = vec4(pos, 0.0f, 1.0f);
|
||||||
|
}
|
@ -3,10 +3,13 @@
|
|||||||
layout(set = 0, binding = 1) uniform sampler2D s_font;
|
layout(set = 0, binding = 1) uniform sampler2D s_font;
|
||||||
|
|
||||||
layout(location = 0) in vec2 v_texcoord;
|
layout(location = 0) in vec2 v_texcoord;
|
||||||
layout(location = 1) in vec4 v_color;
|
|
||||||
|
|
||||||
layout(location = 0) out vec4 o_color;
|
layout(location = 0) out vec4 o_color;
|
||||||
|
|
||||||
|
layout(push_constant)
|
||||||
|
uniform push_data {
|
||||||
|
vec4 color;
|
||||||
|
};
|
||||||
|
|
||||||
float sampleAlpha(float alpha_bias, float dist_range) {
|
float sampleAlpha(float alpha_bias, float dist_range) {
|
||||||
float value = texture(s_font, v_texcoord).r + alpha_bias - 0.5f;
|
float value = texture(s_font, v_texcoord).r + alpha_bias - 0.5f;
|
||||||
float dist = value * dot(vec2(dist_range, dist_range), 1.0f / fwidth(v_texcoord.xy));
|
float dist = value * dot(vec2(dist_range, dist_range), 1.0f / fwidth(v_texcoord.xy));
|
||||||
@ -17,7 +20,7 @@ void main() {
|
|||||||
float r_alpha_center = sampleAlpha(0.0f, 5.0f);
|
float r_alpha_center = sampleAlpha(0.0f, 5.0f);
|
||||||
float r_alpha_shadow = sampleAlpha(0.3f, 5.0f);
|
float r_alpha_shadow = sampleAlpha(0.3f, 5.0f);
|
||||||
|
|
||||||
vec4 r_center = vec4(v_color.rgb, v_color.a * r_alpha_center);
|
vec4 r_center = vec4(color.rgb, color.a * r_alpha_center);
|
||||||
vec4 r_shadow = vec4(0.0f, 0.0f, 0.0f, r_alpha_shadow);
|
vec4 r_shadow = vec4(0.0f, 0.0f, 0.0f, r_alpha_shadow);
|
||||||
|
|
||||||
o_color = mix(r_shadow, r_center, r_alpha_center);
|
o_color = mix(r_shadow, r_center, r_alpha_center);
|
@ -7,14 +7,11 @@ uniform u_hud {
|
|||||||
|
|
||||||
layout(location = 0) in vec2 v_position;
|
layout(location = 0) in vec2 v_position;
|
||||||
layout(location = 1) in uvec2 v_texcoord;
|
layout(location = 1) in uvec2 v_texcoord;
|
||||||
layout(location = 2) in vec4 v_color;
|
|
||||||
|
|
||||||
layout(location = 0) out vec2 o_texcoord;
|
layout(location = 0) out vec2 o_texcoord;
|
||||||
layout(location = 1) out vec4 o_color;
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
o_texcoord = vec2(v_texcoord);
|
o_texcoord = vec2(v_texcoord);
|
||||||
o_color = v_color;
|
|
||||||
|
|
||||||
vec2 pos = 2.0f * (v_position / vec2(g_hud.size)) - 1.0f;
|
vec2 pos = 2.0f * (v_position / vec2(g_hud.size)) - 1.0f;
|
||||||
gl_Position = vec4(pos, 0.0f, 1.0f);
|
gl_Position = vec4(pos, 0.0f, 1.0f);
|
@ -39,9 +39,11 @@ dxvk_shaders = files([
|
|||||||
'shaders/dxvk_unpack_d24s8.comp',
|
'shaders/dxvk_unpack_d24s8.comp',
|
||||||
'shaders/dxvk_unpack_d32s8.comp',
|
'shaders/dxvk_unpack_d32s8.comp',
|
||||||
|
|
||||||
'hud/shaders/hud_line.frag',
|
'hud/shaders/hud_line_frag.frag',
|
||||||
'hud/shaders/hud_text.frag',
|
'hud/shaders/hud_line_vert.vert',
|
||||||
'hud/shaders/hud_vert.vert',
|
|
||||||
|
'hud/shaders/hud_text_frag.frag',
|
||||||
|
'hud/shaders/hud_text_vert.vert',
|
||||||
])
|
])
|
||||||
|
|
||||||
dxvk_src = files([
|
dxvk_src = files([
|
||||||
|
Loading…
x
Reference in New Issue
Block a user