1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +01:00
OpenDX/src/dxvk/dxvk_context.cpp

225 lines
5.6 KiB
C++
Raw Normal View History

2017-10-10 23:32:13 +02:00
#include "dxvk_context.h"
#include "dxvk_main.h"
namespace dxvk {
DxvkContext::DxvkContext(const Rc<vk::DeviceFn>& vkd)
2017-10-11 00:27:33 +02:00
: m_vkd(vkd) {
TRACE(this);
}
2017-10-10 23:32:13 +02:00
DxvkContext::~DxvkContext() {
2017-10-11 00:27:33 +02:00
TRACE(this);
2017-10-10 23:32:13 +02:00
}
void DxvkContext::beginRecording(
const Rc<DxvkCommandList>& cmdList) {
2017-10-11 00:27:33 +02:00
TRACE(this, cmdList);
2017-10-10 23:32:13 +02:00
m_commandList = cmdList;
m_commandList->beginRecording();
// Make sure that we apply the current context state
// to the command buffer when recording draw commands.
m_state.g.flags.clr(
DxvkGraphicsPipelineBit::RenderPassBound);
m_state.g.flags.set(
DxvkGraphicsPipelineBit::PipelineDirty,
DxvkGraphicsPipelineBit::PipelineStateDirty,
DxvkGraphicsPipelineBit::DirtyResources,
DxvkGraphicsPipelineBit::DirtyVertexBuffers,
DxvkGraphicsPipelineBit::DirtyIndexBuffer);
m_state.c.flags.set(
DxvkComputePipelineBit::PipelineDirty,
DxvkComputePipelineBit::DirtyResources);
2017-10-10 23:32:13 +02:00
}
bool DxvkContext::endRecording() {
2017-10-11 00:27:33 +02:00
TRACE(this);
// Any currently active render pass must be
// ended before finalizing the command buffer.
if (m_state.g.flags.test(DxvkGraphicsPipelineBit::RenderPassBound))
this->endRenderPass();
// Finalize the command list
2017-10-10 23:32:13 +02:00
m_commandList->endRecording();
m_commandList = nullptr;
return true;
}
void DxvkContext::clearRenderTarget(
const VkClearAttachment& attachment,
const VkClearRect& clearArea) {
this->flushGraphicsState();
2017-10-10 23:32:13 +02:00
m_vkd->vkCmdClearAttachments(
m_commandList->handle(),
1, &attachment,
1, &clearArea);
}
void DxvkContext::dispatch(
uint32_t wgCountX,
uint32_t wgCountY,
uint32_t wgCountZ) {
this->flushComputeState();
m_vkd->vkCmdDispatch(
m_commandList->handle(),
wgCountX, wgCountY, wgCountZ);
}
void DxvkContext::draw(
uint32_t vertexCount,
uint32_t instanceCount,
uint32_t firstVertex,
uint32_t firstInstance) {
this->flushGraphicsState();
m_vkd->vkCmdDraw(
m_commandList->handle(),
vertexCount,
instanceCount,
firstVertex,
firstInstance);
}
void DxvkContext::drawIndexed(
uint32_t indexCount,
uint32_t instanceCount,
uint32_t firstIndex,
uint32_t vertexOffset,
uint32_t firstInstance) {
this->flushGraphicsState();
m_vkd->vkCmdDrawIndexed(
m_commandList->handle(),
indexCount,
instanceCount,
firstIndex,
vertexOffset,
firstInstance);
}
2017-10-10 23:32:13 +02:00
void DxvkContext::setFramebuffer(
const Rc<DxvkFramebuffer>& fb) {
2017-10-11 00:27:33 +02:00
TRACE(this, fb);
if (m_state.g.fb != fb) {
m_state.g.fb = fb;
if (m_state.g.flags.test(
DxvkGraphicsPipelineBit::RenderPassBound))
this->endRenderPass();
}
}
void DxvkContext::setShader(
VkShaderStageFlagBits stage,
const Rc<DxvkShader>& shader) {
TRACE(this, stage, shader);
DxvkShaderState* state = this->getShaderState(stage);
if (state->shader != shader) {
state->shader = shader;
if (stage == VK_SHADER_STAGE_COMPUTE_BIT) {
m_state.c.flags.set(
DxvkComputePipelineBit::PipelineDirty,
DxvkComputePipelineBit::DirtyResources);
} else {
m_state.g.flags.set(
DxvkGraphicsPipelineBit::PipelineDirty,
DxvkGraphicsPipelineBit::DirtyResources);
}
}
}
void DxvkContext::flushComputeState() {
VkCommandBuffer cmd = m_commandList->handle();
if (m_state.c.flags.test(DxvkComputePipelineBit::PipelineDirty)
&& m_state.c.pipeline != nullptr) {
m_vkd->vkCmdBindPipeline(cmd,
VK_PIPELINE_BIND_POINT_COMPUTE,
m_state.c.pipeline->handle());
}
m_state.c.flags.clr(
DxvkComputePipelineBit::PipelineDirty,
DxvkComputePipelineBit::DirtyResources);
}
void DxvkContext::flushGraphicsState() {
if (!m_state.g.flags.test(DxvkGraphicsPipelineBit::RenderPassBound))
this->beginRenderPass();
}
void DxvkContext::beginRenderPass() {
TRACE(this);
DxvkFramebufferSize fbsize
= m_state.g.fb->size();
2017-10-10 23:32:13 +02:00
VkRenderPassBeginInfo info;
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
info.pNext = nullptr;
info.renderPass = m_state.g.fb->renderPass();
info.framebuffer = m_state.g.fb->handle();
info.renderArea = VkRect2D { { 0, 0 }, { fbsize.width, fbsize.height } };
2017-10-10 23:32:13 +02:00
info.clearValueCount = 0;
info.pClearValues = nullptr;
m_vkd->vkCmdBeginRenderPass(m_commandList->handle(), &info, VK_SUBPASS_CONTENTS_INLINE);
m_state.g.flags.set(DxvkGraphicsPipelineBit::RenderPassBound);
}
void DxvkContext::endRenderPass() {
TRACE(this);
m_vkd->vkCmdEndRenderPass(m_commandList->handle());
m_state.g.flags.clr(DxvkGraphicsPipelineBit::RenderPassBound);
}
DxvkShaderState* DxvkContext::getShaderState(VkShaderStageFlagBits stage) {
switch (stage) {
case VK_SHADER_STAGE_VERTEX_BIT:
return &m_state.g.vs;
case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
return &m_state.g.tcs;
case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
return &m_state.g.tes;
case VK_SHADER_STAGE_GEOMETRY_BIT:
return &m_state.g.gs;
case VK_SHADER_STAGE_FRAGMENT_BIT:
return &m_state.g.fs;
case VK_SHADER_STAGE_COMPUTE_BIT:
return &m_state.c.cs;
default:
return nullptr;
}
2017-10-10 23:32:13 +02:00
}
}