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();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool DxvkContext::endRecording() {
|
2017-10-11 00:27:33 +02:00
|
|
|
TRACE(this);
|
2017-10-11 23:29:05 +02:00
|
|
|
|
|
|
|
if (m_state.fb.flags.test(DxvkFbStateFlags::InsideRenderPass))
|
|
|
|
this->endRenderPass();
|
|
|
|
|
|
|
|
// Finalize the command list
|
2017-10-10 23:32:13 +02:00
|
|
|
m_commandList->endRecording();
|
|
|
|
m_commandList = nullptr;
|
|
|
|
return true;
|
|
|
|
}
|
2017-10-11 23:29:05 +02:00
|
|
|
|
|
|
|
|
|
|
|
void DxvkContext::clearRenderTarget(
|
|
|
|
const VkClearAttachment& attachment,
|
|
|
|
const VkClearRect& clearArea) {
|
|
|
|
if (!m_state.fb.flags.test(DxvkFbStateFlags::InsideRenderPass))
|
|
|
|
this->beginRenderPass();
|
2017-10-10 23:32:13 +02:00
|
|
|
|
2017-10-11 23:29:05 +02:00
|
|
|
m_vkd->vkCmdClearAttachments(
|
|
|
|
m_commandList->handle(),
|
|
|
|
1, &attachment,
|
|
|
|
1, &clearArea);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DxvkContext::draw(
|
|
|
|
uint32_t vertexCount,
|
|
|
|
uint32_t instanceCount,
|
|
|
|
uint32_t firstVertex,
|
|
|
|
uint32_t firstInstance) {
|
|
|
|
this->prepareDraw();
|
|
|
|
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->prepareDraw();
|
|
|
|
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);
|
|
|
|
|
2017-10-11 23:29:05 +02:00
|
|
|
// When changing the framebuffer binding, we end the
|
|
|
|
// current render pass, but beginning the new render
|
|
|
|
// pass is deferred until a draw command is called.
|
|
|
|
if (m_state.fb.framebuffer != fb) {
|
|
|
|
if (m_state.fb.flags.test(DxvkFbStateFlags::InsideRenderPass))
|
|
|
|
this->endRenderPass();
|
|
|
|
|
|
|
|
m_state.fb.framebuffer = fb;
|
|
|
|
m_commandList->trackResource(fb);
|
|
|
|
}
|
2017-10-10 23:32:13 +02:00
|
|
|
|
2017-10-11 23:29:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DxvkContext::setShader(
|
|
|
|
VkShaderStageFlagBits stage,
|
|
|
|
const Rc<DxvkShader>& shader) {
|
|
|
|
TRACE(this, stage, shader);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DxvkContext::flushGraphicsState() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DxvkContext::prepareDraw() {
|
|
|
|
this->flushGraphicsState();
|
|
|
|
|
|
|
|
if (!m_state.fb.flags.test(DxvkFbStateFlags::InsideRenderPass))
|
|
|
|
this->beginRenderPass();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DxvkContext::beginRenderPass() {
|
|
|
|
TRACE(this);
|
|
|
|
|
|
|
|
const DxvkFramebufferSize fbsize
|
|
|
|
= m_state.fb.framebuffer->size();
|
|
|
|
|
2017-10-10 23:32:13 +02:00
|
|
|
VkRenderPassBeginInfo info;
|
|
|
|
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
|
|
|
info.pNext = nullptr;
|
2017-10-11 23:29:05 +02:00
|
|
|
info.renderPass = m_state.fb.framebuffer->renderPass();
|
|
|
|
info.framebuffer = m_state.fb.framebuffer->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(),
|
2017-10-11 23:29:05 +02:00
|
|
|
&info, VK_SUBPASS_CONTENTS_INLINE);
|
|
|
|
m_state.fb.flags.set(DxvkFbStateFlags::InsideRenderPass);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DxvkContext::endRenderPass() {
|
|
|
|
TRACE(this);
|
|
|
|
|
|
|
|
m_vkd->vkCmdEndRenderPass(m_commandList->handle());
|
|
|
|
m_state.fb.flags.clr(DxvkFbStateFlags::InsideRenderPass);
|
2017-10-10 23:32:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|