2017-11-29 20:19:40 +01:00
|
|
|
#include <cstring>
|
|
|
|
|
2017-10-11 09:51:48 +02:00
|
|
|
#include "d3d11_context.h"
|
|
|
|
#include "d3d11_device.h"
|
2018-01-01 20:59:54 +01:00
|
|
|
#include "d3d11_query.h"
|
2017-12-25 20:40:48 +01:00
|
|
|
#include "d3d11_texture.h"
|
2017-10-11 09:51:48 +02:00
|
|
|
|
2017-12-08 22:30:41 +01:00
|
|
|
#include "../dxbc/dxbc_util.h"
|
|
|
|
|
2017-10-11 09:51:48 +02:00
|
|
|
namespace dxvk {
|
|
|
|
|
2017-10-11 15:32:24 +02:00
|
|
|
D3D11DeviceContext::D3D11DeviceContext(
|
2018-01-23 09:23:31 +01:00
|
|
|
D3D11Device* pParent,
|
|
|
|
Rc<DxvkDevice> Device)
|
|
|
|
: m_parent (pParent),
|
|
|
|
m_device (Device),
|
2018-01-20 22:52:18 +01:00
|
|
|
m_csChunk (new DxvkCsChunk()) {
|
2017-12-11 14:11:18 +01:00
|
|
|
// Create default state objects. We won't ever return them
|
|
|
|
// to the application, but we'll use them to apply state.
|
|
|
|
Com<ID3D11BlendState> defaultBlendState;
|
|
|
|
Com<ID3D11DepthStencilState> defaultDepthStencilState;
|
|
|
|
Com<ID3D11RasterizerState> defaultRasterizerState;
|
|
|
|
|
|
|
|
if (FAILED(m_parent->CreateBlendState (nullptr, &defaultBlendState))
|
|
|
|
|| FAILED(m_parent->CreateDepthStencilState(nullptr, &defaultDepthStencilState))
|
|
|
|
|| FAILED(m_parent->CreateRasterizerState (nullptr, &defaultRasterizerState)))
|
|
|
|
throw DxvkError("D3D11DeviceContext: Failed to create default state objects");
|
|
|
|
|
|
|
|
// Apply default state to the context. This is required
|
|
|
|
// in order to initialize the DXVK contex properly.
|
2018-01-20 18:01:43 +01:00
|
|
|
m_defaultBlendState = static_cast<D3D11BlendState*> (defaultBlendState.ptr());
|
2017-12-11 14:11:18 +01:00
|
|
|
m_defaultDepthStencilState = static_cast<D3D11DepthStencilState*>(defaultDepthStencilState.ptr());
|
2018-01-20 18:01:43 +01:00
|
|
|
m_defaultRasterizerState = static_cast<D3D11RasterizerState*> (defaultRasterizerState.ptr());
|
2018-01-10 19:07:55 +01:00
|
|
|
|
2018-01-20 18:01:43 +01:00
|
|
|
EmitCs([
|
|
|
|
dev = m_device,
|
|
|
|
bsState = m_defaultBlendState,
|
|
|
|
dsState = m_defaultDepthStencilState,
|
|
|
|
rsState = m_defaultRasterizerState,
|
|
|
|
blendConst = DxvkBlendConstants {
|
|
|
|
m_state.om.blendFactor[0], m_state.om.blendFactor[1],
|
|
|
|
m_state.om.blendFactor[2], m_state.om.blendFactor[3] },
|
|
|
|
stencilRef = m_state.om.stencilRef
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->beginRecording(dev->createCommandList());
|
|
|
|
|
|
|
|
bsState->BindToContext(ctx, 0xFFFFFFFF);
|
|
|
|
dsState->BindToContext(ctx);
|
|
|
|
rsState->BindToContext(ctx);
|
|
|
|
|
|
|
|
ctx->setBlendConstants (blendConst);
|
|
|
|
ctx->setStencilReference(stencilRef);
|
|
|
|
});
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
D3D11DeviceContext::~D3D11DeviceContext() {
|
2017-11-26 14:01:41 +01:00
|
|
|
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DeviceContext::QueryInterface(
|
2017-10-11 09:51:48 +02:00
|
|
|
REFIID riid,
|
|
|
|
void** ppvObject) {
|
2017-10-15 21:50:34 +02:00
|
|
|
COM_QUERY_IFACE(riid, ppvObject, IUnknown);
|
|
|
|
COM_QUERY_IFACE(riid, ppvObject, ID3D11DeviceChild);
|
2017-10-11 09:51:48 +02:00
|
|
|
COM_QUERY_IFACE(riid, ppvObject, ID3D11DeviceContext);
|
|
|
|
|
2018-03-05 01:07:09 +01:00
|
|
|
if (riid == __uuidof(ID3DUserDefinedAnnotation))
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
|
2017-10-11 09:51:48 +02:00
|
|
|
Logger::warn("D3D11DeviceContext::QueryInterface: Unknown interface query");
|
2018-03-05 01:07:09 +01:00
|
|
|
Logger::warn(str::format(riid));
|
2017-10-11 09:51:48 +02:00
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::GetDevice(ID3D11Device **ppDevice) {
|
2017-10-11 15:32:24 +02:00
|
|
|
*ppDevice = ref(m_parent);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::ClearState() {
|
2017-12-07 12:45:02 +01:00
|
|
|
this->IASetInputLayout(nullptr);
|
2017-12-06 18:54:01 +01:00
|
|
|
this->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED);
|
2017-12-09 15:57:05 +01:00
|
|
|
this->IASetIndexBuffer(nullptr, DXGI_FORMAT_UNKNOWN, 0);
|
2017-12-06 12:11:59 +01:00
|
|
|
|
2017-12-20 17:37:46 +01:00
|
|
|
for (uint32_t i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) {
|
|
|
|
ID3D11Buffer* buffer = nullptr;
|
|
|
|
const UINT offset = 0;
|
|
|
|
const UINT stride = 0;
|
|
|
|
|
|
|
|
this->IASetVertexBuffers(i, 1, &buffer, &offset, &stride);
|
|
|
|
}
|
2017-12-06 12:11:59 +01:00
|
|
|
|
2017-12-20 17:37:46 +01:00
|
|
|
this->VSSetShader(nullptr, nullptr, 0);
|
|
|
|
this->HSSetShader(nullptr, nullptr, 0);
|
|
|
|
this->DSSetShader(nullptr, nullptr, 0);
|
2017-12-18 12:53:53 +01:00
|
|
|
this->GSSetShader(nullptr, nullptr, 0);
|
2017-12-07 10:12:48 +01:00
|
|
|
this->PSSetShader(nullptr, nullptr, 0);
|
2017-12-20 17:37:46 +01:00
|
|
|
this->CSSetShader(nullptr, nullptr, 0);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) {
|
|
|
|
ID3D11Buffer* buffer = nullptr;
|
|
|
|
|
|
|
|
this->VSSetConstantBuffers(i, 1, &buffer);
|
|
|
|
this->HSSetConstantBuffers(i, 1, &buffer);
|
|
|
|
this->DSSetConstantBuffers(i, 1, &buffer);
|
|
|
|
this->GSSetConstantBuffers(i, 1, &buffer);
|
|
|
|
this->PSSetConstantBuffers(i, 1, &buffer);
|
|
|
|
this->CSSetConstantBuffers(i, 1, &buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) {
|
|
|
|
ID3D11ShaderResourceView* view = nullptr;
|
|
|
|
|
|
|
|
this->VSSetShaderResources(i, 1, &view);
|
|
|
|
this->HSSetShaderResources(i, 1, &view);
|
|
|
|
this->DSSetShaderResources(i, 1, &view);
|
|
|
|
this->GSSetShaderResources(i, 1, &view);
|
|
|
|
this->PSSetShaderResources(i, 1, &view);
|
|
|
|
this->CSSetShaderResources(i, 1, &view);
|
|
|
|
}
|
2017-12-06 12:11:59 +01:00
|
|
|
|
2017-12-20 17:37:46 +01:00
|
|
|
for (uint32_t i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) {
|
|
|
|
ID3D11SamplerState* sampler = nullptr;
|
|
|
|
|
|
|
|
this->VSSetSamplers(i, 1, &sampler);
|
|
|
|
this->HSSetSamplers(i, 1, &sampler);
|
|
|
|
this->DSSetSamplers(i, 1, &sampler);
|
|
|
|
this->GSSetSamplers(i, 1, &sampler);
|
|
|
|
this->PSSetSamplers(i, 1, &sampler);
|
|
|
|
this->CSSetSamplers(i, 1, &sampler);
|
|
|
|
}
|
2017-12-06 12:11:59 +01:00
|
|
|
|
2017-12-28 19:05:53 +01:00
|
|
|
for (uint32_t i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) {
|
|
|
|
ID3D11UnorderedAccessView* uav = nullptr;
|
|
|
|
|
|
|
|
this->CSSetUnorderedAccessViews(i, 1, &uav, nullptr);
|
|
|
|
}
|
|
|
|
|
2017-12-06 12:11:59 +01:00
|
|
|
this->OMSetRenderTargets(0, nullptr, nullptr);
|
2017-12-10 01:56:07 +01:00
|
|
|
this->OMSetBlendState(nullptr, nullptr, D3D11_DEFAULT_SAMPLE_MASK);
|
|
|
|
this->OMSetDepthStencilState(nullptr, 0);
|
2017-12-06 12:11:59 +01:00
|
|
|
|
|
|
|
this->RSSetState(nullptr);
|
|
|
|
this->RSSetViewports(0, nullptr);
|
|
|
|
this->RSSetScissorRects(0, nullptr);
|
|
|
|
|
|
|
|
// this->SOSetTargets(0, nullptr, nullptr);
|
|
|
|
|
2018-03-09 16:47:20 +01:00
|
|
|
this->SetPredication(nullptr, FALSE);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::Begin(ID3D11Asynchronous *pAsync) {
|
2018-02-18 22:34:23 +01:00
|
|
|
Com<ID3D11Query> query;
|
|
|
|
|
|
|
|
if (SUCCEEDED(pAsync->QueryInterface(__uuidof(ID3D11Query), reinterpret_cast<void**>(&query)))) {
|
|
|
|
Com<D3D11Query> queryPtr = static_cast<D3D11Query*>(query.ptr());
|
|
|
|
|
|
|
|
if (queryPtr->HasBeginEnabled()) {
|
|
|
|
const uint32_t revision = queryPtr->Reset();
|
|
|
|
|
|
|
|
EmitCs([revision, queryPtr] (DxvkContext* ctx) {
|
|
|
|
queryPtr->Begin(ctx, revision);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::End(ID3D11Asynchronous *pAsync) {
|
2018-02-18 22:34:23 +01:00
|
|
|
Com<ID3D11Query> query;
|
|
|
|
|
|
|
|
if (SUCCEEDED(pAsync->QueryInterface(__uuidof(ID3D11Query), reinterpret_cast<void**>(&query)))) {
|
|
|
|
Com<D3D11Query> queryPtr = static_cast<D3D11Query*>(query.ptr());
|
|
|
|
|
|
|
|
if (queryPtr->HasBeginEnabled()) {
|
|
|
|
EmitCs([queryPtr] (DxvkContext* ctx) {
|
|
|
|
queryPtr->End(ctx);
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
const uint32_t revision = queryPtr->Reset();
|
|
|
|
|
|
|
|
EmitCs([revision, queryPtr] (DxvkContext* ctx) {
|
|
|
|
queryPtr->Signal(ctx, revision);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DeviceContext::GetData(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11Asynchronous* pAsync,
|
|
|
|
void* pData,
|
|
|
|
UINT DataSize,
|
|
|
|
UINT GetDataFlags) {
|
2018-02-07 12:35:40 +01:00
|
|
|
// Make sure that we can safely write to the memory
|
|
|
|
// location pointed to by pData if it is specified.
|
|
|
|
if (DataSize == 0)
|
|
|
|
pData = nullptr;
|
|
|
|
|
2018-01-29 17:04:07 +01:00
|
|
|
if (pData != nullptr && pAsync->GetDataSize() != DataSize) {
|
|
|
|
Logger::err(str::format("D3D11DeviceContext: GetData: Data size mismatch: ", pAsync->GetDataSize(), ",", DataSize));
|
2018-01-01 20:59:54 +01:00
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
|
2018-02-18 22:34:23 +01:00
|
|
|
// Flush in order to make sure the query commands get dispatched
|
|
|
|
if ((GetDataFlags & D3D11_ASYNC_GETDATA_DONOTFLUSH) == 0)
|
|
|
|
Flush();
|
|
|
|
|
2018-01-01 20:59:54 +01:00
|
|
|
// This method handles various different but incompatible interfaces,
|
|
|
|
// so we have to find out what we are actually dealing with
|
|
|
|
Com<ID3D11Query> query;
|
|
|
|
|
|
|
|
if (SUCCEEDED(pAsync->QueryInterface(__uuidof(ID3D11Query), reinterpret_cast<void**>(&query))))
|
|
|
|
return static_cast<D3D11Query*>(query.ptr())->GetData(pData, GetDataFlags);
|
|
|
|
|
|
|
|
// The interface is not supported
|
|
|
|
Logger::err("D3D11DeviceContext: GetData: Unsupported Async type");
|
|
|
|
return E_INVALIDARG;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::SetPredication(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11Predicate* pPredicate,
|
2018-03-06 18:34:34 +01:00
|
|
|
BOOL PredicateValue) {
|
2018-03-09 16:47:20 +01:00
|
|
|
static bool s_errorShown = false;
|
|
|
|
|
|
|
|
if (!std::exchange(s_errorShown, true))
|
|
|
|
Logger::err("D3D11DeviceContext::SetPredication: Stub");
|
|
|
|
|
|
|
|
m_state.pr.predicateObject = static_cast<D3D11Query*>(pPredicate);
|
|
|
|
m_state.pr.predicateValue = PredicateValue;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::GetPredication(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11Predicate** ppPredicate,
|
2018-03-06 18:34:34 +01:00
|
|
|
BOOL* pPredicateValue) {
|
2018-03-09 16:47:20 +01:00
|
|
|
if (ppPredicate != nullptr)
|
|
|
|
*ppPredicate = m_state.pr.predicateObject.ref();
|
|
|
|
|
|
|
|
if (pPredicateValue != nullptr)
|
|
|
|
*pPredicateValue = m_state.pr.predicateValue;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::CopySubresourceRegion(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11Resource* pDstResource,
|
|
|
|
UINT DstSubresource,
|
|
|
|
UINT DstX,
|
|
|
|
UINT DstY,
|
|
|
|
UINT DstZ,
|
|
|
|
ID3D11Resource* pSrcResource,
|
|
|
|
UINT SrcSubresource,
|
|
|
|
const D3D11_BOX* pSrcBox) {
|
2017-12-30 19:10:45 +01:00
|
|
|
D3D11_RESOURCE_DIMENSION dstResourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
|
|
|
|
D3D11_RESOURCE_DIMENSION srcResourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
|
|
|
|
|
|
|
|
pDstResource->GetType(&dstResourceDim);
|
|
|
|
pSrcResource->GetType(&srcResourceDim);
|
|
|
|
|
|
|
|
if (dstResourceDim != srcResourceDim) {
|
|
|
|
Logger::err("D3D11DeviceContext: CopySubresourceRegion: Mismatched resource types");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dstResourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) {
|
2018-02-03 21:14:55 +01:00
|
|
|
auto dstBuffer = static_cast<D3D11Buffer*>(pDstResource)->GetBufferSlice();
|
|
|
|
auto srcBuffer = static_cast<D3D11Buffer*>(pSrcResource)->GetBufferSlice();
|
|
|
|
|
|
|
|
VkDeviceSize srcOffset = 0;
|
|
|
|
VkDeviceSize srcLength = srcBuffer.length();
|
|
|
|
|
|
|
|
if (pSrcBox != nullptr) {
|
2018-02-23 15:16:44 +01:00
|
|
|
if (pSrcBox->left > pSrcBox->right)
|
2018-02-03 21:14:55 +01:00
|
|
|
return; // no-op, but legal
|
|
|
|
|
|
|
|
srcOffset = pSrcBox->left;
|
|
|
|
srcLength = pSrcBox->right - pSrcBox->left;
|
|
|
|
}
|
|
|
|
|
|
|
|
EmitCs([
|
|
|
|
cDstSlice = dstBuffer.subSlice(DstX, srcLength),
|
|
|
|
cSrcSlice = srcBuffer.subSlice(srcOffset, srcLength)
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->copyBuffer(
|
|
|
|
cDstSlice.buffer(),
|
|
|
|
cDstSlice.offset(),
|
|
|
|
cSrcSlice.buffer(),
|
|
|
|
cSrcSlice.offset(),
|
|
|
|
cSrcSlice.length());
|
|
|
|
});
|
2017-12-30 19:10:45 +01:00
|
|
|
} else {
|
2018-01-05 01:15:56 +01:00
|
|
|
const D3D11TextureInfo* dstTextureInfo = GetCommonTextureInfo(pDstResource);
|
|
|
|
const D3D11TextureInfo* srcTextureInfo = GetCommonTextureInfo(pSrcResource);
|
2017-12-30 19:10:45 +01:00
|
|
|
|
2018-01-06 02:09:07 +01:00
|
|
|
const DxvkFormatInfo* dstFormatInfo = imageFormatInfo(dstTextureInfo->image->info().format);
|
|
|
|
const DxvkFormatInfo* srcFormatInfo = imageFormatInfo(srcTextureInfo->image->info().format);
|
|
|
|
|
2018-02-20 13:08:50 +01:00
|
|
|
const VkImageSubresource dstSubresource = GetSubresourceFromIndex(dstFormatInfo->aspectMask, dstTextureInfo->image->info().mipLevels, DstSubresource);
|
|
|
|
const VkImageSubresource srcSubresource = GetSubresourceFromIndex(srcFormatInfo->aspectMask, srcTextureInfo->image->info().mipLevels, SrcSubresource);
|
2018-01-06 02:09:07 +01:00
|
|
|
|
2017-12-30 19:10:45 +01:00
|
|
|
VkOffset3D srcOffset = { 0, 0, 0 };
|
|
|
|
VkOffset3D dstOffset = {
|
|
|
|
static_cast<int32_t>(DstX),
|
|
|
|
static_cast<int32_t>(DstY),
|
|
|
|
static_cast<int32_t>(DstZ) };
|
|
|
|
|
2018-01-06 02:09:07 +01:00
|
|
|
VkExtent3D extent = srcTextureInfo->image->mipLevelExtent(srcSubresource.mipLevel);
|
2017-12-30 19:10:45 +01:00
|
|
|
|
|
|
|
if (pSrcBox != nullptr) {
|
|
|
|
if (pSrcBox->left >= pSrcBox->right
|
|
|
|
|| pSrcBox->top >= pSrcBox->bottom
|
|
|
|
|| pSrcBox->front >= pSrcBox->back)
|
|
|
|
return; // no-op, but legal
|
|
|
|
|
|
|
|
srcOffset.x = pSrcBox->left;
|
|
|
|
srcOffset.y = pSrcBox->top;
|
|
|
|
srcOffset.z = pSrcBox->front;
|
|
|
|
|
|
|
|
extent.width = pSrcBox->right - pSrcBox->left;
|
|
|
|
extent.height = pSrcBox->bottom - pSrcBox->top;
|
|
|
|
extent.depth = pSrcBox->back - pSrcBox->front;
|
|
|
|
}
|
|
|
|
|
2017-12-31 00:25:19 +01:00
|
|
|
const VkImageSubresourceLayers dstLayers = {
|
|
|
|
dstSubresource.aspectMask,
|
|
|
|
dstSubresource.mipLevel,
|
|
|
|
dstSubresource.arrayLayer, 1 };
|
|
|
|
|
|
|
|
const VkImageSubresourceLayers srcLayers = {
|
|
|
|
srcSubresource.aspectMask,
|
|
|
|
srcSubresource.mipLevel,
|
|
|
|
srcSubresource.arrayLayer, 1 };
|
2017-12-30 19:10:45 +01:00
|
|
|
|
2018-01-20 19:30:31 +01:00
|
|
|
EmitCs([
|
|
|
|
cDstImage = dstTextureInfo->image,
|
|
|
|
cSrcImage = srcTextureInfo->image,
|
|
|
|
cDstLayers = dstLayers,
|
|
|
|
cSrcLayers = srcLayers,
|
|
|
|
cDstOffset = dstOffset,
|
|
|
|
cSrcOffset = srcOffset,
|
|
|
|
cExtent = extent
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->copyImage(
|
|
|
|
cDstImage, cDstLayers, cDstOffset,
|
|
|
|
cSrcImage, cSrcLayers, cSrcOffset,
|
|
|
|
cExtent);
|
|
|
|
});
|
2017-12-30 19:10:45 +01:00
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::CopyResource(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11Resource* pDstResource,
|
|
|
|
ID3D11Resource* pSrcResource) {
|
2017-12-28 19:05:53 +01:00
|
|
|
D3D11_RESOURCE_DIMENSION dstResourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
|
|
|
|
D3D11_RESOURCE_DIMENSION srcResourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
|
|
|
|
|
|
|
|
pDstResource->GetType(&dstResourceDim);
|
|
|
|
pSrcResource->GetType(&srcResourceDim);
|
|
|
|
|
|
|
|
if (dstResourceDim != srcResourceDim) {
|
|
|
|
Logger::err("D3D11DeviceContext: CopyResource: Mismatched resource types");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dstResourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) {
|
|
|
|
auto dstBuffer = static_cast<D3D11Buffer*>(pDstResource)->GetBufferSlice();
|
|
|
|
auto srcBuffer = static_cast<D3D11Buffer*>(pSrcResource)->GetBufferSlice();
|
|
|
|
|
|
|
|
if (dstBuffer.length() != srcBuffer.length()) {
|
|
|
|
Logger::err("D3D11DeviceContext: CopyResource: Mismatched buffer size");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-01-20 19:30:31 +01:00
|
|
|
EmitCs([
|
|
|
|
cDstBuffer = std::move(dstBuffer),
|
|
|
|
cSrcBuffer = std::move(srcBuffer)
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->copyBuffer(
|
|
|
|
cDstBuffer.buffer(),
|
|
|
|
cDstBuffer.offset(),
|
|
|
|
cSrcBuffer.buffer(),
|
|
|
|
cSrcBuffer.offset(),
|
|
|
|
cSrcBuffer.length());
|
|
|
|
});
|
2017-12-28 19:05:53 +01:00
|
|
|
} else {
|
2018-01-14 10:39:59 +01:00
|
|
|
const D3D11TextureInfo* dstTextureInfo = GetCommonTextureInfo(pDstResource);
|
|
|
|
const D3D11TextureInfo* srcTextureInfo = GetCommonTextureInfo(pSrcResource);
|
|
|
|
|
2018-01-14 21:17:51 +01:00
|
|
|
const DxvkFormatInfo* dstFormatInfo = imageFormatInfo(dstTextureInfo->image->info().format);
|
|
|
|
const DxvkFormatInfo* srcFormatInfo = imageFormatInfo(srcTextureInfo->image->info().format);
|
2018-01-14 10:39:59 +01:00
|
|
|
|
2018-01-14 21:17:51 +01:00
|
|
|
for (uint32_t i = 0; i < srcTextureInfo->image->info().mipLevels; i++) {
|
|
|
|
VkExtent3D extent = srcTextureInfo->image->mipLevelExtent(i);
|
2018-01-14 10:39:59 +01:00
|
|
|
|
2018-02-20 13:08:50 +01:00
|
|
|
const VkImageSubresourceLayers dstLayers = { dstFormatInfo->aspectMask, i, 0, dstTextureInfo->image->info().numLayers };
|
|
|
|
const VkImageSubresourceLayers srcLayers = { srcFormatInfo->aspectMask, i, 0, srcTextureInfo->image->info().numLayers };
|
2018-01-20 19:30:31 +01:00
|
|
|
|
|
|
|
EmitCs([
|
|
|
|
cDstImage = dstTextureInfo->image,
|
|
|
|
cSrcImage = srcTextureInfo->image,
|
|
|
|
cDstLayers = dstLayers,
|
|
|
|
cSrcLayers = srcLayers,
|
|
|
|
cExtent = extent
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->copyImage(
|
|
|
|
cDstImage, cDstLayers, VkOffset3D { 0, 0, 0 },
|
2018-01-21 01:57:12 +01:00
|
|
|
cSrcImage, cSrcLayers, VkOffset3D { 0, 0, 0 },
|
2018-01-20 19:30:31 +01:00
|
|
|
cExtent);
|
|
|
|
});
|
2018-01-14 21:17:51 +01:00
|
|
|
}
|
2017-12-28 19:05:53 +01:00
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
2018-01-14 21:17:51 +01:00
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::CopyStructureCount(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11Buffer* pDstBuffer,
|
|
|
|
UINT DstAlignedByteOffset,
|
|
|
|
ID3D11UnorderedAccessView* pSrcView) {
|
2018-01-11 12:23:55 +01:00
|
|
|
auto buf = static_cast<D3D11Buffer*>(pDstBuffer);
|
|
|
|
auto uav = static_cast<D3D11UnorderedAccessView*>(pSrcView);
|
2018-01-14 21:17:51 +01:00
|
|
|
|
2018-01-20 19:30:31 +01:00
|
|
|
EmitCs([
|
|
|
|
cDstSlice = buf->GetBufferSlice(DstAlignedByteOffset),
|
|
|
|
cSrcSlice = uav->GetCounterSlice()
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->copyBuffer(
|
|
|
|
cDstSlice.buffer(),
|
|
|
|
cDstSlice.offset(),
|
|
|
|
cSrcSlice.buffer(),
|
|
|
|
cSrcSlice.offset(),
|
|
|
|
sizeof(uint32_t));
|
|
|
|
});
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::ClearRenderTargetView(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11RenderTargetView* pRenderTargetView,
|
|
|
|
const FLOAT ColorRGBA[4]) {
|
2017-12-04 13:39:37 +01:00
|
|
|
auto rtv = static_cast<D3D11RenderTargetView*>(pRenderTargetView);
|
2018-02-24 23:39:22 +01:00
|
|
|
|
|
|
|
if (rtv == nullptr)
|
|
|
|
return;
|
2017-12-01 00:52:39 +01:00
|
|
|
|
2017-11-29 20:19:40 +01:00
|
|
|
// Find out whether the given attachment is currently bound
|
|
|
|
// or not, and if it is, which attachment index it has.
|
|
|
|
int32_t attachmentIndex = -1;
|
|
|
|
|
2017-12-09 03:53:42 +01:00
|
|
|
for (uint32_t i = 0; i < m_state.om.renderTargetViews.size(); i++) {
|
|
|
|
if (m_state.om.renderTargetViews.at(i) == rtv)
|
|
|
|
attachmentIndex = i;
|
2017-11-29 20:19:40 +01:00
|
|
|
}
|
|
|
|
|
2017-12-01 00:52:39 +01:00
|
|
|
// Copy the clear color into a clear value structure.
|
|
|
|
// This should also work for images that don nott have
|
|
|
|
// a floating point format.
|
2018-02-24 23:39:22 +01:00
|
|
|
const Rc<DxvkImageView> view = rtv->GetImageView();
|
|
|
|
|
2017-12-01 00:52:39 +01:00
|
|
|
VkClearColorValue clearValue;
|
|
|
|
std::memcpy(clearValue.float32, ColorRGBA,
|
|
|
|
sizeof(clearValue.float32));
|
2017-11-29 20:19:40 +01:00
|
|
|
|
2017-12-01 00:52:39 +01:00
|
|
|
if (attachmentIndex >= 0) {
|
|
|
|
// Image is bound to the pipeline for rendering. We can
|
|
|
|
// use the clear function that operates on attachments.
|
|
|
|
VkClearAttachment clearInfo;
|
|
|
|
clearInfo.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
|
|
clearInfo.colorAttachment = static_cast<uint32_t>(attachmentIndex);
|
|
|
|
clearInfo.clearValue.color = clearValue;
|
|
|
|
|
|
|
|
// Clear the full area. On FL 9.x, only the first array
|
|
|
|
// layer will be cleared, rather than all array layers.
|
|
|
|
VkClearRect clearRect;
|
|
|
|
clearRect.rect.offset.x = 0;
|
|
|
|
clearRect.rect.offset.y = 0;
|
2018-02-24 23:39:22 +01:00
|
|
|
clearRect.rect.extent.width = view->mipLevelExtent(0).width;
|
|
|
|
clearRect.rect.extent.height = view->mipLevelExtent(0).height;
|
2017-12-01 00:52:39 +01:00
|
|
|
clearRect.baseArrayLayer = 0;
|
2018-02-24 23:39:22 +01:00
|
|
|
clearRect.layerCount = view->info().numLayers;
|
2017-12-01 00:52:39 +01:00
|
|
|
|
|
|
|
if (m_parent->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0)
|
|
|
|
clearRect.layerCount = 1;
|
|
|
|
|
2018-01-20 19:30:31 +01:00
|
|
|
EmitCs([
|
|
|
|
cClearInfo = clearInfo,
|
|
|
|
cClearRect = clearRect
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->clearRenderTarget(cClearInfo, cClearRect);
|
|
|
|
});
|
2017-12-01 00:52:39 +01:00
|
|
|
} else {
|
|
|
|
// Image is not bound to the pipeline. We can still clear
|
|
|
|
// it, but we'll have to use a generic clear function.
|
2018-01-20 19:30:31 +01:00
|
|
|
EmitCs([
|
|
|
|
cClearValue = clearValue,
|
2018-02-24 23:39:22 +01:00
|
|
|
cDstView = view
|
2018-01-20 19:30:31 +01:00
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->clearColorImage(cDstView->image(),
|
|
|
|
cClearValue, cDstView->subresources());
|
|
|
|
});
|
2017-12-01 00:52:39 +01:00
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::ClearUnorderedAccessViewUint(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11UnorderedAccessView* pUnorderedAccessView,
|
|
|
|
const UINT Values[4]) {
|
2018-02-04 23:57:43 +01:00
|
|
|
auto uav = static_cast<D3D11UnorderedAccessView*>(pUnorderedAccessView);
|
|
|
|
|
2018-02-24 23:39:22 +01:00
|
|
|
if (uav == nullptr)
|
|
|
|
return;
|
|
|
|
|
2018-02-04 23:57:43 +01:00
|
|
|
if (uav->GetResourceType() == D3D11_RESOURCE_DIMENSION_BUFFER) {
|
2018-03-07 16:29:13 +01:00
|
|
|
const Rc<DxvkBufferView> bufferView = uav->GetBufferView();
|
|
|
|
|
|
|
|
if (bufferView->info().format == VK_FORMAT_R32_UINT) {
|
|
|
|
EmitCs([
|
|
|
|
cClearValue = Values[0],
|
|
|
|
cDstSlice = bufferView->slice()
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->clearBuffer(
|
|
|
|
cDstSlice.buffer(),
|
|
|
|
cDstSlice.offset(),
|
|
|
|
cDstSlice.length(),
|
|
|
|
cClearValue);
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
Logger::err("D3D11: ClearUnorderedAccessViewUint: Not supported for typed buffers");
|
|
|
|
}
|
2018-02-04 23:57:43 +01:00
|
|
|
} else {
|
2018-03-07 16:29:13 +01:00
|
|
|
// FIXME floating point formats are not handled correctly
|
|
|
|
// yet, we might need to create an image view with an
|
|
|
|
// integer format and clear that.
|
2018-02-04 23:57:43 +01:00
|
|
|
VkClearColorValue clearValue;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < 4; i++)
|
|
|
|
clearValue.uint32[i] = Values[i];
|
|
|
|
|
|
|
|
EmitCs([
|
|
|
|
cClearValue = clearValue,
|
|
|
|
cDstView = uav->GetImageView()
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->clearColorImage(cDstView->image(),
|
|
|
|
cClearValue, cDstView->subresources());
|
|
|
|
});
|
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::ClearUnorderedAccessViewFloat(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11UnorderedAccessView* pUnorderedAccessView,
|
|
|
|
const FLOAT Values[4]) {
|
|
|
|
Logger::err("D3D11DeviceContext::ClearUnorderedAccessViewFloat: Not implemented");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::ClearDepthStencilView(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11DepthStencilView* pDepthStencilView,
|
|
|
|
UINT ClearFlags,
|
|
|
|
FLOAT Depth,
|
|
|
|
UINT8 Stencil) {
|
2017-12-09 03:53:42 +01:00
|
|
|
auto dsv = static_cast<D3D11DepthStencilView*>(pDepthStencilView);
|
2018-02-24 23:39:22 +01:00
|
|
|
|
|
|
|
if (dsv == nullptr)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Figure out which aspects to clear based
|
|
|
|
// on the image format and the clear flags.
|
|
|
|
const Rc<DxvkImageView> view = dsv->GetImageView();
|
2017-12-09 03:53:42 +01:00
|
|
|
|
2018-01-23 19:01:07 +01:00
|
|
|
VkImageAspectFlags aspectMask = 0;
|
|
|
|
|
|
|
|
if (ClearFlags & D3D11_CLEAR_DEPTH)
|
|
|
|
aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
|
|
|
|
|
|
|
if (ClearFlags & D3D11_CLEAR_STENCIL)
|
|
|
|
aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
|
|
|
|
2018-01-28 21:13:37 +01:00
|
|
|
const DxvkFormatInfo* formatInfo =
|
2018-02-24 23:39:22 +01:00
|
|
|
imageFormatInfo(view->info().format);
|
2018-01-28 21:13:37 +01:00
|
|
|
aspectMask &= formatInfo->aspectMask;
|
|
|
|
|
2017-12-09 03:53:42 +01:00
|
|
|
VkClearDepthStencilValue clearValue;
|
|
|
|
clearValue.depth = Depth;
|
|
|
|
clearValue.stencil = Stencil;
|
|
|
|
|
|
|
|
if (m_state.om.depthStencilView == dsv) {
|
|
|
|
// Image is bound to the pipeline for rendering. We can
|
|
|
|
// use the clear function that operates on attachments.
|
|
|
|
VkClearAttachment clearInfo;
|
2018-01-23 19:01:07 +01:00
|
|
|
clearInfo.aspectMask = aspectMask;
|
2017-12-09 03:53:42 +01:00
|
|
|
clearInfo.colorAttachment = 0;
|
|
|
|
clearInfo.clearValue.depthStencil = clearValue;
|
|
|
|
|
|
|
|
// Clear the full area
|
|
|
|
VkClearRect clearRect;
|
|
|
|
clearRect.rect.offset.x = 0;
|
|
|
|
clearRect.rect.offset.y = 0;
|
2018-02-24 23:39:22 +01:00
|
|
|
clearRect.rect.extent.width = view->mipLevelExtent(0).width;
|
|
|
|
clearRect.rect.extent.height = view->mipLevelExtent(0).height;
|
2017-12-09 03:53:42 +01:00
|
|
|
clearRect.baseArrayLayer = 0;
|
2018-02-24 23:39:22 +01:00
|
|
|
clearRect.layerCount = view->info().numLayers;
|
2017-12-09 03:53:42 +01:00
|
|
|
|
|
|
|
// FIXME Is this correct? Docs don't say anything
|
|
|
|
if (m_parent->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0)
|
|
|
|
clearRect.layerCount = 1;
|
|
|
|
|
2018-01-20 19:30:31 +01:00
|
|
|
EmitCs([
|
|
|
|
cClearInfo = clearInfo,
|
|
|
|
cClearRect = clearRect
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->clearRenderTarget(cClearInfo, cClearRect);
|
|
|
|
});
|
2017-12-09 03:53:42 +01:00
|
|
|
} else {
|
2018-01-20 19:30:31 +01:00
|
|
|
EmitCs([
|
|
|
|
cClearValue = clearValue,
|
2018-02-24 23:39:22 +01:00
|
|
|
cDstView = view,
|
2018-01-23 19:01:07 +01:00
|
|
|
cAspectMask = aspectMask
|
2018-01-20 19:30:31 +01:00
|
|
|
] (DxvkContext* ctx) {
|
2018-01-23 19:01:07 +01:00
|
|
|
VkImageSubresourceRange subresources = cDstView->subresources();
|
|
|
|
subresources.aspectMask = cAspectMask;
|
|
|
|
|
2018-01-20 19:30:31 +01:00
|
|
|
ctx->clearDepthStencilImage(cDstView->image(),
|
2018-01-23 19:01:07 +01:00
|
|
|
cClearValue, subresources);
|
2018-01-20 19:30:31 +01:00
|
|
|
});
|
2017-12-09 03:53:42 +01:00
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::GenerateMips(ID3D11ShaderResourceView* pShaderResourceView) {
|
2018-01-20 09:46:54 +01:00
|
|
|
auto view = static_cast<D3D11ShaderResourceView*>(pShaderResourceView);
|
|
|
|
|
|
|
|
if (view->GetResourceType() != D3D11_RESOURCE_DIMENSION_BUFFER) {
|
2018-01-20 19:30:31 +01:00
|
|
|
EmitCs([cDstImageView = view->GetImageView()]
|
|
|
|
(DxvkContext* ctx) {
|
|
|
|
ctx->generateMipmaps(
|
|
|
|
cDstImageView->image(),
|
|
|
|
cDstImageView->subresources());
|
|
|
|
});
|
2018-01-20 09:46:54 +01:00
|
|
|
} else {
|
|
|
|
Logger::err("D3D11DeviceContext: GenerateMips called on a buffer");
|
|
|
|
}
|
|
|
|
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::UpdateSubresource(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11Resource* pDstResource,
|
|
|
|
UINT DstSubresource,
|
|
|
|
const D3D11_BOX* pDstBox,
|
|
|
|
const void* pSrcData,
|
|
|
|
UINT SrcRowPitch,
|
|
|
|
UINT SrcDepthPitch) {
|
2017-12-08 19:39:33 +01:00
|
|
|
// We need a different code path for buffers
|
|
|
|
D3D11_RESOURCE_DIMENSION resourceType;
|
|
|
|
pDstResource->GetType(&resourceType);
|
|
|
|
|
|
|
|
if (resourceType == D3D11_RESOURCE_DIMENSION_BUFFER) {
|
2017-12-14 19:07:08 +01:00
|
|
|
const auto bufferResource = static_cast<D3D11Buffer*>(pDstResource);
|
2017-12-15 19:11:10 +01:00
|
|
|
const auto bufferSlice = bufferResource->GetBufferSlice();
|
2017-12-08 19:39:33 +01:00
|
|
|
|
2018-01-20 21:42:11 +01:00
|
|
|
VkDeviceSize offset = bufferSlice.offset();
|
|
|
|
VkDeviceSize size = bufferSlice.length();
|
2017-12-08 19:39:33 +01:00
|
|
|
|
|
|
|
if (pDstBox != nullptr) {
|
|
|
|
offset = pDstBox->left;
|
|
|
|
size = pDstBox->right - pDstBox->left;
|
|
|
|
}
|
|
|
|
|
2017-12-14 19:11:13 +01:00
|
|
|
if (offset + size > bufferSlice.length()) {
|
2017-12-25 20:40:48 +01:00
|
|
|
Logger::err("D3D11DeviceContext: Buffer update range out of bounds");
|
2017-12-14 19:07:08 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-01-18 11:55:27 +01:00
|
|
|
if (size == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (((size == bufferSlice.length())
|
2018-01-18 18:50:44 +01:00
|
|
|
&& (bufferSlice.buffer()->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))) {
|
2018-01-23 12:16:28 +01:00
|
|
|
D3D11_MAPPED_SUBRESOURCE mappedSr;
|
|
|
|
Map(pDstResource, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedSr);
|
|
|
|
std::memcpy(mappedSr.pData, pSrcData, size);
|
|
|
|
Unmap(pDstResource, 0);
|
2018-01-18 11:55:27 +01:00
|
|
|
} else {
|
2018-01-23 16:43:55 +01:00
|
|
|
DxvkDataSlice dataSlice = AllocUpdateBufferSlice(size);
|
|
|
|
std::memcpy(dataSlice.ptr(), pSrcData, size);
|
|
|
|
|
2018-01-20 21:42:11 +01:00
|
|
|
EmitCs([
|
2018-01-23 16:43:55 +01:00
|
|
|
cDataBuffer = std::move(dataSlice),
|
2018-01-20 21:42:11 +01:00
|
|
|
cBufferSlice = bufferSlice.subSlice(offset, size)
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->updateBuffer(
|
|
|
|
cBufferSlice.buffer(),
|
|
|
|
cBufferSlice.offset(),
|
|
|
|
cBufferSlice.length(),
|
2018-01-23 16:43:55 +01:00
|
|
|
cDataBuffer.ptr());
|
2018-01-20 21:42:11 +01:00
|
|
|
});
|
2017-12-14 19:07:08 +01:00
|
|
|
}
|
2017-12-08 19:39:33 +01:00
|
|
|
} else {
|
2018-01-05 01:15:56 +01:00
|
|
|
const D3D11TextureInfo* textureInfo
|
|
|
|
= GetCommonTextureInfo(pDstResource);
|
2017-12-25 20:40:48 +01:00
|
|
|
|
2018-01-06 02:09:07 +01:00
|
|
|
const VkImageSubresource subresource =
|
|
|
|
GetSubresourceFromIndex(VK_IMAGE_ASPECT_COLOR_BIT,
|
|
|
|
textureInfo->image->info().mipLevels, DstSubresource);
|
|
|
|
|
2017-12-25 20:40:48 +01:00
|
|
|
VkOffset3D offset = { 0, 0, 0 };
|
2018-01-06 02:09:07 +01:00
|
|
|
VkExtent3D extent = textureInfo->image->mipLevelExtent(subresource.mipLevel);
|
2017-12-25 20:40:48 +01:00
|
|
|
|
|
|
|
if (pDstBox != nullptr) {
|
|
|
|
if (pDstBox->left >= pDstBox->right
|
|
|
|
|| pDstBox->top >= pDstBox->bottom
|
|
|
|
|| pDstBox->front >= pDstBox->back)
|
|
|
|
return; // no-op, but legal
|
|
|
|
|
|
|
|
offset.x = pDstBox->left;
|
|
|
|
offset.y = pDstBox->top;
|
|
|
|
offset.z = pDstBox->front;
|
|
|
|
|
|
|
|
extent.width = pDstBox->right - pDstBox->left;
|
|
|
|
extent.height = pDstBox->bottom - pDstBox->top;
|
|
|
|
extent.depth = pDstBox->back - pDstBox->front;
|
|
|
|
}
|
|
|
|
|
2018-01-06 02:09:07 +01:00
|
|
|
const VkImageSubresourceLayers layers = {
|
|
|
|
subresource.aspectMask,
|
|
|
|
subresource.mipLevel,
|
|
|
|
subresource.arrayLayer, 1 };
|
2017-12-25 20:40:48 +01:00
|
|
|
|
2018-01-20 21:42:11 +01:00
|
|
|
auto formatInfo = imageFormatInfo(
|
|
|
|
textureInfo->image->info().format);
|
|
|
|
|
|
|
|
const VkExtent3D regionExtent = util::computeBlockCount(extent, formatInfo->blockSize);
|
|
|
|
|
|
|
|
const VkDeviceSize bytesPerRow = regionExtent.width * formatInfo->elementSize;
|
|
|
|
const VkDeviceSize bytesPerLayer = regionExtent.height * bytesPerRow;
|
|
|
|
const VkDeviceSize bytesTotal = regionExtent.depth * bytesPerLayer;
|
|
|
|
|
2018-01-23 16:43:55 +01:00
|
|
|
DxvkDataSlice imageDataBuffer = AllocUpdateBufferSlice(bytesTotal);
|
2018-01-20 21:42:11 +01:00
|
|
|
|
|
|
|
util::packImageData(
|
2018-01-23 16:43:55 +01:00
|
|
|
reinterpret_cast<char*>(imageDataBuffer.ptr()),
|
2018-01-20 21:42:11 +01:00
|
|
|
reinterpret_cast<const char*>(pSrcData),
|
|
|
|
regionExtent, formatInfo->elementSize,
|
2017-12-25 20:40:48 +01:00
|
|
|
SrcRowPitch, SrcDepthPitch);
|
2018-01-20 21:42:11 +01:00
|
|
|
|
|
|
|
EmitCs([
|
|
|
|
cDstImage = textureInfo->image,
|
|
|
|
cDstLayers = layers,
|
|
|
|
cDstOffset = offset,
|
|
|
|
cDstExtent = extent,
|
|
|
|
cSrcData = std::move(imageDataBuffer),
|
|
|
|
cSrcBytesPerRow = bytesPerRow,
|
|
|
|
cSrcBytesPerLayer = bytesPerLayer
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->updateImage(cDstImage, cDstLayers,
|
2018-01-23 16:43:55 +01:00
|
|
|
cDstOffset, cDstExtent, cSrcData.ptr(),
|
2018-01-20 21:42:11 +01:00
|
|
|
cSrcBytesPerRow, cSrcBytesPerLayer);
|
|
|
|
});
|
2017-12-08 19:39:33 +01:00
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::SetResourceMinLOD(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11Resource* pResource,
|
|
|
|
FLOAT MinLOD) {
|
|
|
|
Logger::err("D3D11DeviceContext::SetResourceMinLOD: Not implemented");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
FLOAT STDMETHODCALLTYPE D3D11DeviceContext::GetResourceMinLOD(ID3D11Resource* pResource) {
|
2017-10-11 09:51:48 +02:00
|
|
|
Logger::err("D3D11DeviceContext::GetResourceMinLOD: Not implemented");
|
|
|
|
return 0.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::ResolveSubresource(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11Resource* pDstResource,
|
|
|
|
UINT DstSubresource,
|
|
|
|
ID3D11Resource* pSrcResource,
|
|
|
|
UINT SrcSubresource,
|
|
|
|
DXGI_FORMAT Format) {
|
2018-01-28 18:06:41 +01:00
|
|
|
D3D11_RESOURCE_DIMENSION dstResourceType;
|
|
|
|
D3D11_RESOURCE_DIMENSION srcResourceType;
|
|
|
|
|
|
|
|
pDstResource->GetType(&dstResourceType);
|
|
|
|
pSrcResource->GetType(&srcResourceType);
|
|
|
|
|
|
|
|
if (dstResourceType != D3D11_RESOURCE_DIMENSION_TEXTURE2D
|
|
|
|
|| srcResourceType != D3D11_RESOURCE_DIMENSION_TEXTURE2D) {
|
|
|
|
Logger::err("D3D11: ResolveSubresource: Incompatible resources");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto dstTexture = static_cast<D3D11Texture2D*>(pDstResource);
|
|
|
|
auto srcTexture = static_cast<D3D11Texture2D*>(pSrcResource);
|
|
|
|
|
|
|
|
D3D11_TEXTURE2D_DESC dstDesc;
|
|
|
|
D3D11_TEXTURE2D_DESC srcDesc;
|
|
|
|
|
|
|
|
dstTexture->GetDesc(&dstDesc);
|
|
|
|
srcTexture->GetDesc(&srcDesc);
|
|
|
|
|
2018-01-30 01:18:43 +01:00
|
|
|
if (dstDesc.SampleDesc.Count != 1) {
|
2018-01-28 18:06:41 +01:00
|
|
|
Logger::err("D3D11: ResolveSubresource: Resource sample count invalid");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const D3D11TextureInfo* dstTextureInfo = GetCommonTextureInfo(pDstResource);
|
|
|
|
const D3D11TextureInfo* srcTextureInfo = GetCommonTextureInfo(pSrcResource);
|
|
|
|
|
|
|
|
const DxgiFormatInfo dstFormatInfo = m_parent->LookupFormat(dstDesc.Format, DxgiFormatMode::Any);
|
|
|
|
const DxgiFormatInfo srcFormatInfo = m_parent->LookupFormat(srcDesc.Format, DxgiFormatMode::Any);
|
|
|
|
|
|
|
|
const VkImageSubresource dstSubresource =
|
|
|
|
GetSubresourceFromIndex(dstFormatInfo.aspect,
|
|
|
|
dstTextureInfo->image->info().mipLevels, DstSubresource);
|
|
|
|
|
|
|
|
const VkImageSubresource srcSubresource =
|
|
|
|
GetSubresourceFromIndex(srcFormatInfo.aspect,
|
|
|
|
srcTextureInfo->image->info().mipLevels, SrcSubresource);
|
|
|
|
|
2018-01-30 02:20:28 +01:00
|
|
|
const VkImageSubresourceLayers dstSubresourceLayers = {
|
|
|
|
dstSubresource.aspectMask,
|
|
|
|
dstSubresource.mipLevel,
|
|
|
|
dstSubresource.arrayLayer, 1 };
|
|
|
|
|
|
|
|
const VkImageSubresourceLayers srcSubresourceLayers = {
|
|
|
|
srcSubresource.aspectMask,
|
|
|
|
srcSubresource.mipLevel,
|
|
|
|
srcSubresource.arrayLayer, 1 };
|
|
|
|
|
2018-01-30 01:18:43 +01:00
|
|
|
if (srcDesc.SampleDesc.Count == 1) {
|
|
|
|
EmitCs([
|
|
|
|
cDstImage = dstTextureInfo->image,
|
|
|
|
cSrcImage = srcTextureInfo->image,
|
|
|
|
cDstLayers = dstSubresourceLayers,
|
|
|
|
cSrcLayers = srcSubresourceLayers
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->copyImage(
|
|
|
|
cDstImage, cDstLayers, VkOffset3D { 0, 0, 0 },
|
|
|
|
cSrcImage, cSrcLayers, VkOffset3D { 0, 0, 0 },
|
|
|
|
cDstImage->mipLevelExtent(cDstLayers.mipLevel));
|
|
|
|
});
|
2018-02-20 22:26:23 +01:00
|
|
|
} else {
|
|
|
|
const VkFormat format = m_parent->LookupFormat(
|
|
|
|
Format, DxgiFormatMode::Any).format;
|
2018-01-28 18:06:41 +01:00
|
|
|
|
|
|
|
EmitCs([
|
|
|
|
cDstImage = dstTextureInfo->image,
|
|
|
|
cSrcImage = srcTextureInfo->image,
|
|
|
|
cDstSubres = dstSubresourceLayers,
|
2018-02-20 22:26:23 +01:00
|
|
|
cSrcSubres = srcSubresourceLayers,
|
|
|
|
cFormat = format
|
2018-01-28 18:06:41 +01:00
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->resolveImage(
|
|
|
|
cDstImage, cDstSubres,
|
2018-02-20 22:26:23 +01:00
|
|
|
cSrcImage, cSrcSubres,
|
|
|
|
cFormat);
|
2018-01-28 18:06:41 +01:00
|
|
|
});
|
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::DrawAuto() {
|
2017-10-11 09:51:48 +02:00
|
|
|
Logger::err("D3D11DeviceContext::DrawAuto: Not implemented");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::Draw(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT VertexCount,
|
|
|
|
UINT StartVertexLocation) {
|
2018-01-20 18:26:17 +01:00
|
|
|
EmitCs([=] (DxvkContext* ctx) {
|
|
|
|
ctx->draw(
|
|
|
|
VertexCount, 1,
|
|
|
|
StartVertexLocation, 0);
|
|
|
|
});
|
|
|
|
|
2018-01-13 23:09:03 +01:00
|
|
|
m_drawCount += 1;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::DrawIndexed(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT IndexCount,
|
|
|
|
UINT StartIndexLocation,
|
|
|
|
INT BaseVertexLocation) {
|
2018-01-20 18:26:17 +01:00
|
|
|
EmitCs([=] (DxvkContext* ctx) {
|
|
|
|
ctx->drawIndexed(
|
|
|
|
IndexCount, 1,
|
|
|
|
StartIndexLocation,
|
|
|
|
BaseVertexLocation, 0);
|
|
|
|
});
|
|
|
|
|
2018-01-13 23:09:03 +01:00
|
|
|
m_drawCount += 1;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::DrawInstanced(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT VertexCountPerInstance,
|
|
|
|
UINT InstanceCount,
|
|
|
|
UINT StartVertexLocation,
|
|
|
|
UINT StartInstanceLocation) {
|
2018-01-20 18:26:17 +01:00
|
|
|
EmitCs([=] (DxvkContext* ctx) {
|
|
|
|
ctx->draw(
|
|
|
|
VertexCountPerInstance,
|
|
|
|
InstanceCount,
|
|
|
|
StartVertexLocation,
|
|
|
|
StartInstanceLocation);
|
|
|
|
});
|
|
|
|
|
2018-01-13 23:09:03 +01:00
|
|
|
m_drawCount += 1;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::DrawIndexedInstanced(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT IndexCountPerInstance,
|
|
|
|
UINT InstanceCount,
|
|
|
|
UINT StartIndexLocation,
|
|
|
|
INT BaseVertexLocation,
|
|
|
|
UINT StartInstanceLocation) {
|
2018-01-20 18:26:17 +01:00
|
|
|
EmitCs([=] (DxvkContext* ctx) {
|
|
|
|
ctx->drawIndexed(
|
|
|
|
IndexCountPerInstance,
|
|
|
|
InstanceCount,
|
|
|
|
StartIndexLocation,
|
|
|
|
BaseVertexLocation,
|
|
|
|
StartInstanceLocation);
|
|
|
|
});
|
|
|
|
|
2018-01-13 23:09:03 +01:00
|
|
|
m_drawCount += 1;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::DrawIndexedInstancedIndirect(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11Buffer* pBufferForArgs,
|
|
|
|
UINT AlignedByteOffsetForArgs) {
|
2017-12-31 01:31:08 +01:00
|
|
|
D3D11Buffer* buffer = static_cast<D3D11Buffer*>(pBufferForArgs);
|
2017-12-31 00:25:19 +01:00
|
|
|
|
2018-01-20 18:26:17 +01:00
|
|
|
EmitCs([bufferSlice = buffer->GetBufferSlice(AlignedByteOffsetForArgs)]
|
|
|
|
(DxvkContext* ctx) {
|
|
|
|
ctx->drawIndexedIndirect(
|
|
|
|
bufferSlice, 1, 0);
|
|
|
|
});
|
|
|
|
|
2018-01-13 23:09:03 +01:00
|
|
|
m_drawCount += 1;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::DrawInstancedIndirect(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11Buffer* pBufferForArgs,
|
|
|
|
UINT AlignedByteOffsetForArgs) {
|
2017-12-31 01:31:08 +01:00
|
|
|
D3D11Buffer* buffer = static_cast<D3D11Buffer*>(pBufferForArgs);
|
2017-12-31 00:25:19 +01:00
|
|
|
|
2018-01-20 18:26:17 +01:00
|
|
|
EmitCs([bufferSlice = buffer->GetBufferSlice(AlignedByteOffsetForArgs)]
|
|
|
|
(DxvkContext* ctx) {
|
|
|
|
ctx->drawIndirect(bufferSlice, 1, 0);
|
|
|
|
});
|
|
|
|
|
2018-01-13 23:09:03 +01:00
|
|
|
m_drawCount += 1;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::Dispatch(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT ThreadGroupCountX,
|
|
|
|
UINT ThreadGroupCountY,
|
|
|
|
UINT ThreadGroupCountZ) {
|
2018-01-20 18:26:17 +01:00
|
|
|
EmitCs([=] (DxvkContext* ctx) {
|
|
|
|
ctx->dispatch(
|
|
|
|
ThreadGroupCountX,
|
|
|
|
ThreadGroupCountY,
|
|
|
|
ThreadGroupCountZ);
|
|
|
|
});
|
|
|
|
|
2018-01-13 23:09:03 +01:00
|
|
|
m_drawCount += 1;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::DispatchIndirect(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11Buffer* pBufferForArgs,
|
|
|
|
UINT AlignedByteOffsetForArgs) {
|
2017-12-31 01:31:08 +01:00
|
|
|
D3D11Buffer* buffer = static_cast<D3D11Buffer*>(pBufferForArgs);
|
2017-12-31 00:25:19 +01:00
|
|
|
|
2018-01-20 18:26:17 +01:00
|
|
|
EmitCs([bufferSlice = buffer->GetBufferSlice(AlignedByteOffsetForArgs)]
|
|
|
|
(DxvkContext* ctx) {
|
|
|
|
ctx->dispatchIndirect(bufferSlice);
|
|
|
|
});
|
|
|
|
|
2018-01-13 23:09:03 +01:00
|
|
|
m_drawCount += 1;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::IASetInputLayout(ID3D11InputLayout* pInputLayout) {
|
2018-03-10 11:44:27 +01:00
|
|
|
auto inputLayout = static_cast<D3D11InputLayout*>(pInputLayout);
|
2017-12-07 12:45:02 +01:00
|
|
|
|
|
|
|
if (m_state.ia.inputLayout != inputLayout) {
|
|
|
|
m_state.ia.inputLayout = inputLayout;
|
2018-03-10 11:44:27 +01:00
|
|
|
ApplyInputLayout();
|
2017-12-07 12:45:02 +01:00
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY Topology) {
|
2017-12-06 18:54:01 +01:00
|
|
|
if (m_state.ia.primitiveTopology != Topology) {
|
|
|
|
m_state.ia.primitiveTopology = Topology;
|
2018-03-10 11:44:27 +01:00
|
|
|
ApplyPrimitiveTopology();
|
2017-12-06 18:54:01 +01:00
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::IASetVertexBuffers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppVertexBuffers,
|
|
|
|
const UINT* pStrides,
|
|
|
|
const UINT* pOffsets) {
|
2017-12-07 14:03:15 +01:00
|
|
|
for (uint32_t i = 0; i < NumBuffers; i++) {
|
2017-12-20 17:37:46 +01:00
|
|
|
auto newBuffer = static_cast<D3D11Buffer*>(ppVertexBuffers[i]);
|
2017-12-15 19:11:10 +01:00
|
|
|
|
2018-03-10 10:39:07 +01:00
|
|
|
m_state.ia.vertexBuffers[StartSlot + i].buffer = newBuffer;
|
|
|
|
m_state.ia.vertexBuffers[StartSlot + i].offset = pOffsets[i];
|
|
|
|
m_state.ia.vertexBuffers[StartSlot + i].stride = pStrides[i];
|
2017-12-09 15:57:05 +01:00
|
|
|
|
2018-03-10 10:39:07 +01:00
|
|
|
BindVertexBuffer(StartSlot + i, newBuffer, pOffsets[i], pStrides[i]);
|
2017-12-07 14:03:15 +01:00
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::IASetIndexBuffer(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11Buffer* pIndexBuffer,
|
|
|
|
DXGI_FORMAT Format,
|
|
|
|
UINT Offset) {
|
2017-12-20 17:37:46 +01:00
|
|
|
auto newBuffer = static_cast<D3D11Buffer*>(pIndexBuffer);
|
2017-12-08 01:51:49 +01:00
|
|
|
|
2017-12-20 17:37:46 +01:00
|
|
|
m_state.ia.indexBuffer.buffer = newBuffer;
|
|
|
|
m_state.ia.indexBuffer.offset = Offset;
|
|
|
|
m_state.ia.indexBuffer.format = Format;
|
2017-12-08 01:51:49 +01:00
|
|
|
|
2018-03-10 10:39:07 +01:00
|
|
|
BindIndexBuffer(newBuffer, Offset, Format);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::IAGetInputLayout(ID3D11InputLayout** ppInputLayout) {
|
2017-12-07 12:45:02 +01:00
|
|
|
*ppInputLayout = m_state.ia.inputLayout.ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::IAGetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY* pTopology) {
|
2017-12-06 18:54:01 +01:00
|
|
|
*pTopology = m_state.ia.primitiveTopology;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::IAGetVertexBuffers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppVertexBuffers,
|
|
|
|
UINT* pStrides,
|
|
|
|
UINT* pOffsets) {
|
2018-01-23 19:10:48 +01:00
|
|
|
for (uint32_t i = 0; i < NumBuffers; i++) {
|
|
|
|
if (ppVertexBuffers != nullptr)
|
|
|
|
ppVertexBuffers[i] = m_state.ia.vertexBuffers[StartSlot + i].buffer.ref();
|
|
|
|
|
|
|
|
if (pStrides != nullptr)
|
|
|
|
pStrides[i] = m_state.ia.vertexBuffers[StartSlot + i].stride;
|
|
|
|
|
|
|
|
if (pOffsets != nullptr)
|
|
|
|
pOffsets[i] = m_state.ia.vertexBuffers[StartSlot + i].offset;
|
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::IAGetIndexBuffer(
|
2018-01-23 19:10:48 +01:00
|
|
|
ID3D11Buffer** ppIndexBuffer,
|
|
|
|
DXGI_FORMAT* pFormat,
|
|
|
|
UINT* pOffset) {
|
|
|
|
if (ppIndexBuffer != nullptr)
|
|
|
|
*ppIndexBuffer = m_state.ia.indexBuffer.buffer.ref();
|
|
|
|
|
|
|
|
if (pFormat != nullptr)
|
|
|
|
*pFormat = m_state.ia.indexBuffer.format;
|
|
|
|
|
|
|
|
if (pOffset != nullptr)
|
|
|
|
*pOffset = m_state.ia.indexBuffer.offset;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::VSSetShader(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11VertexShader* pVertexShader,
|
|
|
|
ID3D11ClassInstance* const* ppClassInstances,
|
|
|
|
UINT NumClassInstances) {
|
2017-12-07 10:12:48 +01:00
|
|
|
auto shader = static_cast<D3D11VertexShader*>(pVertexShader);
|
|
|
|
|
|
|
|
if (NumClassInstances != 0)
|
|
|
|
Logger::err("D3D11DeviceContext::VSSetShader: Class instances not supported");
|
|
|
|
|
|
|
|
if (m_state.vs.shader != shader) {
|
|
|
|
m_state.vs.shader = shader;
|
2018-03-10 10:19:07 +01:00
|
|
|
BindShader(shader, VK_SHADER_STAGE_VERTEX_BIT);
|
2017-12-07 10:12:48 +01:00
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::VSSetConstantBuffers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers) {
|
2018-03-10 11:16:52 +01:00
|
|
|
this->SetConstantBuffers(
|
2017-12-08 22:30:41 +01:00
|
|
|
DxbcProgramType::VertexShader,
|
2017-12-20 17:37:46 +01:00
|
|
|
m_state.vs.constantBuffers,
|
2017-12-08 19:39:33 +01:00
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::VSSetShaderResources(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView* const* ppShaderResourceViews) {
|
2018-03-10 11:16:52 +01:00
|
|
|
this->SetShaderResources(
|
2017-12-10 01:56:07 +01:00
|
|
|
DxbcProgramType::VertexShader,
|
2017-12-20 17:37:46 +01:00
|
|
|
m_state.vs.shaderResources,
|
2017-12-10 01:56:07 +01:00
|
|
|
StartSlot, NumViews,
|
|
|
|
ppShaderResourceViews);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::VSSetSamplers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState* const* ppSamplers) {
|
2018-03-10 11:16:52 +01:00
|
|
|
this->SetSamplers(
|
2017-12-09 21:17:26 +01:00
|
|
|
DxbcProgramType::VertexShader,
|
2017-12-20 17:37:46 +01:00
|
|
|
m_state.vs.samplers,
|
2017-12-09 21:17:26 +01:00
|
|
|
StartSlot, NumSamplers,
|
|
|
|
ppSamplers);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::VSGetShader(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11VertexShader** ppVertexShader,
|
|
|
|
ID3D11ClassInstance** ppClassInstances,
|
|
|
|
UINT* pNumClassInstances) {
|
2017-12-11 14:21:24 +01:00
|
|
|
if (ppVertexShader != nullptr)
|
|
|
|
*ppVertexShader = m_state.vs.shader.ref();
|
|
|
|
|
2018-01-17 23:49:26 +01:00
|
|
|
if (pNumClassInstances != nullptr)
|
2017-12-11 14:21:24 +01:00
|
|
|
*pNumClassInstances = 0;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::VSGetConstantBuffers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppConstantBuffers) {
|
2017-12-20 17:37:46 +01:00
|
|
|
for (uint32_t i = 0; i < NumBuffers; i++)
|
|
|
|
ppConstantBuffers[i] = m_state.vs.constantBuffers.at(StartSlot + i).ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::VSGetShaderResources(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView** ppShaderResourceViews) {
|
2017-12-20 17:37:46 +01:00
|
|
|
for (uint32_t i = 0; i < NumViews; i++)
|
|
|
|
ppShaderResourceViews[i] = m_state.vs.shaderResources.at(StartSlot + i).ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::VSGetSamplers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState** ppSamplers) {
|
2017-12-20 17:37:46 +01:00
|
|
|
for (uint32_t i = 0; i < NumSamplers; i++)
|
|
|
|
ppSamplers[i] = m_state.vs.samplers.at(StartSlot + i).ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::HSSetShader(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11HullShader* pHullShader,
|
|
|
|
ID3D11ClassInstance* const* ppClassInstances,
|
|
|
|
UINT NumClassInstances) {
|
2018-02-26 17:29:10 +01:00
|
|
|
auto shader = static_cast<D3D11HullShader*>(pHullShader);
|
|
|
|
|
|
|
|
if (NumClassInstances != 0)
|
|
|
|
Logger::err("D3D11DeviceContext::HSSetShader: Class instances not supported");
|
|
|
|
|
|
|
|
if (m_state.hs.shader != shader) {
|
|
|
|
m_state.hs.shader = shader;
|
2018-03-10 10:19:07 +01:00
|
|
|
BindShader(shader, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
|
2018-02-26 17:29:10 +01:00
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::HSSetShaderResources(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView* const* ppShaderResourceViews) {
|
2018-03-10 11:16:52 +01:00
|
|
|
this->SetShaderResources(
|
2017-12-20 17:37:46 +01:00
|
|
|
DxbcProgramType::HullShader,
|
|
|
|
m_state.hs.shaderResources,
|
|
|
|
StartSlot, NumViews,
|
|
|
|
ppShaderResourceViews);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::HSSetConstantBuffers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers) {
|
2018-03-10 11:16:52 +01:00
|
|
|
this->SetConstantBuffers(
|
2017-12-20 17:37:46 +01:00
|
|
|
DxbcProgramType::HullShader,
|
|
|
|
m_state.hs.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::HSSetSamplers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState* const* ppSamplers) {
|
2018-03-10 11:16:52 +01:00
|
|
|
this->SetSamplers(
|
2017-12-20 17:37:46 +01:00
|
|
|
DxbcProgramType::HullShader,
|
|
|
|
m_state.hs.samplers,
|
|
|
|
StartSlot, NumSamplers,
|
|
|
|
ppSamplers);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::HSGetShader(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11HullShader** ppHullShader,
|
|
|
|
ID3D11ClassInstance** ppClassInstances,
|
|
|
|
UINT* pNumClassInstances) {
|
2017-12-20 17:37:46 +01:00
|
|
|
if (ppHullShader != nullptr)
|
|
|
|
*ppHullShader = m_state.hs.shader.ref();
|
|
|
|
|
2018-01-17 23:49:26 +01:00
|
|
|
if (pNumClassInstances != nullptr)
|
2017-12-20 17:37:46 +01:00
|
|
|
*pNumClassInstances = 0;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::HSGetConstantBuffers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppConstantBuffers) {
|
2017-12-20 17:37:46 +01:00
|
|
|
for (uint32_t i = 0; i < NumBuffers; i++)
|
|
|
|
ppConstantBuffers[i] = m_state.hs.constantBuffers.at(StartSlot + i).ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::HSGetShaderResources(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView** ppShaderResourceViews) {
|
2017-12-20 17:37:46 +01:00
|
|
|
for (uint32_t i = 0; i < NumViews; i++)
|
|
|
|
ppShaderResourceViews[i] = m_state.hs.shaderResources.at(StartSlot + i).ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::HSGetSamplers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState** ppSamplers) {
|
2017-12-20 17:37:46 +01:00
|
|
|
for (uint32_t i = 0; i < NumSamplers; i++)
|
|
|
|
ppSamplers[i] = m_state.hs.samplers.at(StartSlot + i).ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::DSSetShader(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11DomainShader* pDomainShader,
|
|
|
|
ID3D11ClassInstance* const* ppClassInstances,
|
|
|
|
UINT NumClassInstances) {
|
2018-02-26 17:29:10 +01:00
|
|
|
auto shader = static_cast<D3D11DomainShader*>(pDomainShader);
|
|
|
|
|
|
|
|
if (NumClassInstances != 0)
|
|
|
|
Logger::err("D3D11DeviceContext::DSSetShader: Class instances not supported");
|
|
|
|
|
|
|
|
if (m_state.ds.shader != shader) {
|
|
|
|
m_state.ds.shader = shader;
|
2018-03-10 10:19:07 +01:00
|
|
|
BindShader(shader, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
|
2018-02-26 17:29:10 +01:00
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::DSSetShaderResources(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView* const* ppShaderResourceViews) {
|
2018-03-10 11:16:52 +01:00
|
|
|
this->SetShaderResources(
|
2017-12-20 17:37:46 +01:00
|
|
|
DxbcProgramType::DomainShader,
|
|
|
|
m_state.ds.shaderResources,
|
|
|
|
StartSlot, NumViews,
|
|
|
|
ppShaderResourceViews);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::DSSetConstantBuffers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers) {
|
2018-03-10 11:16:52 +01:00
|
|
|
this->SetConstantBuffers(
|
2017-12-20 17:37:46 +01:00
|
|
|
DxbcProgramType::DomainShader,
|
|
|
|
m_state.ds.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::DSSetSamplers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState* const* ppSamplers) {
|
2018-03-10 11:16:52 +01:00
|
|
|
this->SetSamplers(
|
2017-12-20 17:37:46 +01:00
|
|
|
DxbcProgramType::DomainShader,
|
|
|
|
m_state.ds.samplers,
|
|
|
|
StartSlot, NumSamplers,
|
|
|
|
ppSamplers);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::DSGetShader(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11DomainShader** ppDomainShader,
|
|
|
|
ID3D11ClassInstance** ppClassInstances,
|
|
|
|
UINT* pNumClassInstances) {
|
2017-12-20 17:37:46 +01:00
|
|
|
if (ppDomainShader != nullptr)
|
|
|
|
*ppDomainShader = m_state.ds.shader.ref();
|
|
|
|
|
2018-01-17 23:49:26 +01:00
|
|
|
if (pNumClassInstances != nullptr)
|
2017-12-20 17:37:46 +01:00
|
|
|
*pNumClassInstances = 0;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::DSGetConstantBuffers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppConstantBuffers) {
|
2017-12-20 17:37:46 +01:00
|
|
|
for (uint32_t i = 0; i < NumBuffers; i++)
|
|
|
|
ppConstantBuffers[i] = m_state.ds.constantBuffers.at(StartSlot + i).ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::DSGetShaderResources(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView** ppShaderResourceViews) {
|
2017-12-20 17:37:46 +01:00
|
|
|
for (uint32_t i = 0; i < NumViews; i++)
|
|
|
|
ppShaderResourceViews[i] = m_state.ds.shaderResources.at(StartSlot + i).ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::DSGetSamplers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState** ppSamplers) {
|
2017-12-20 17:37:46 +01:00
|
|
|
for (uint32_t i = 0; i < NumSamplers; i++)
|
|
|
|
ppSamplers[i] = m_state.ds.samplers.at(StartSlot + i).ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::GSSetShader(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11GeometryShader* pShader,
|
|
|
|
ID3D11ClassInstance* const* ppClassInstances,
|
|
|
|
UINT NumClassInstances) {
|
2017-12-18 12:53:53 +01:00
|
|
|
auto shader = static_cast<D3D11GeometryShader*>(pShader);
|
|
|
|
|
|
|
|
if (NumClassInstances != 0)
|
|
|
|
Logger::err("D3D11DeviceContext::GSSetShader: Class instances not supported");
|
|
|
|
|
|
|
|
if (m_state.gs.shader != shader) {
|
|
|
|
m_state.gs.shader = shader;
|
2018-03-10 10:19:07 +01:00
|
|
|
BindShader(shader, VK_SHADER_STAGE_GEOMETRY_BIT);
|
2017-12-18 12:53:53 +01:00
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::GSSetConstantBuffers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers) {
|
2018-03-10 11:16:52 +01:00
|
|
|
this->SetConstantBuffers(
|
2017-12-18 12:53:53 +01:00
|
|
|
DxbcProgramType::GeometryShader,
|
2017-12-20 17:37:46 +01:00
|
|
|
m_state.gs.constantBuffers,
|
2017-12-18 12:53:53 +01:00
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::GSSetShaderResources(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView* const* ppShaderResourceViews) {
|
2018-03-10 11:16:52 +01:00
|
|
|
this->SetShaderResources(
|
2017-12-18 12:53:53 +01:00
|
|
|
DxbcProgramType::GeometryShader,
|
2017-12-20 17:37:46 +01:00
|
|
|
m_state.gs.shaderResources,
|
2017-12-18 12:53:53 +01:00
|
|
|
StartSlot, NumViews,
|
|
|
|
ppShaderResourceViews);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::GSSetSamplers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState* const* ppSamplers) {
|
2018-03-10 11:16:52 +01:00
|
|
|
this->SetSamplers(
|
2017-12-18 12:53:53 +01:00
|
|
|
DxbcProgramType::GeometryShader,
|
2017-12-20 17:37:46 +01:00
|
|
|
m_state.gs.samplers,
|
2017-12-18 12:53:53 +01:00
|
|
|
StartSlot, NumSamplers,
|
|
|
|
ppSamplers);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::GSGetShader(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11GeometryShader** ppGeometryShader,
|
|
|
|
ID3D11ClassInstance** ppClassInstances,
|
|
|
|
UINT* pNumClassInstances) {
|
2017-12-18 12:53:53 +01:00
|
|
|
if (ppGeometryShader != nullptr)
|
|
|
|
*ppGeometryShader = m_state.gs.shader.ref();
|
|
|
|
|
2018-01-17 23:49:26 +01:00
|
|
|
if (pNumClassInstances != nullptr)
|
2017-12-18 12:53:53 +01:00
|
|
|
*pNumClassInstances = 0;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::GSGetConstantBuffers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppConstantBuffers) {
|
2017-12-18 12:53:53 +01:00
|
|
|
for (uint32_t i = 0; i < NumBuffers; i++)
|
|
|
|
ppConstantBuffers[i] = m_state.gs.constantBuffers.at(StartSlot + i).ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::GSGetShaderResources(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView** ppShaderResourceViews) {
|
2017-12-18 12:53:53 +01:00
|
|
|
for (uint32_t i = 0; i < NumViews; i++)
|
|
|
|
ppShaderResourceViews[i] = m_state.gs.shaderResources.at(StartSlot + i).ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::GSGetSamplers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState** ppSamplers) {
|
2017-12-18 12:53:53 +01:00
|
|
|
for (uint32_t i = 0; i < NumSamplers; i++)
|
|
|
|
ppSamplers[i] = m_state.gs.samplers.at(StartSlot + i).ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::PSSetShader(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11PixelShader* pPixelShader,
|
|
|
|
ID3D11ClassInstance* const* ppClassInstances,
|
|
|
|
UINT NumClassInstances) {
|
2017-12-07 10:12:48 +01:00
|
|
|
auto shader = static_cast<D3D11PixelShader*>(pPixelShader);
|
|
|
|
|
|
|
|
if (NumClassInstances != 0)
|
2017-12-07 12:45:02 +01:00
|
|
|
Logger::err("D3D11DeviceContext::PSSetShader: Class instances not supported");
|
2017-12-07 10:12:48 +01:00
|
|
|
|
|
|
|
if (m_state.ps.shader != shader) {
|
|
|
|
m_state.ps.shader = shader;
|
2018-03-10 10:19:07 +01:00
|
|
|
BindShader(shader, VK_SHADER_STAGE_FRAGMENT_BIT);
|
2017-12-07 10:12:48 +01:00
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::PSSetConstantBuffers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers) {
|
2018-03-10 11:16:52 +01:00
|
|
|
this->SetConstantBuffers(
|
2017-12-08 22:30:41 +01:00
|
|
|
DxbcProgramType::PixelShader,
|
2017-12-20 17:37:46 +01:00
|
|
|
m_state.ps.constantBuffers,
|
2017-12-08 19:39:33 +01:00
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::PSSetShaderResources(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView* const* ppShaderResourceViews) {
|
2018-03-10 11:16:52 +01:00
|
|
|
this->SetShaderResources(
|
2017-12-10 01:56:07 +01:00
|
|
|
DxbcProgramType::PixelShader,
|
2017-12-20 17:37:46 +01:00
|
|
|
m_state.ps.shaderResources,
|
2017-12-10 01:56:07 +01:00
|
|
|
StartSlot, NumViews,
|
|
|
|
ppShaderResourceViews);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::PSSetSamplers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState* const* ppSamplers) {
|
2018-03-10 11:16:52 +01:00
|
|
|
this->SetSamplers(
|
2017-12-09 21:17:26 +01:00
|
|
|
DxbcProgramType::PixelShader,
|
2017-12-20 17:37:46 +01:00
|
|
|
m_state.ps.samplers,
|
2017-12-09 21:17:26 +01:00
|
|
|
StartSlot, NumSamplers,
|
|
|
|
ppSamplers);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::PSGetShader(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11PixelShader** ppPixelShader,
|
|
|
|
ID3D11ClassInstance** ppClassInstances,
|
|
|
|
UINT* pNumClassInstances) {
|
2017-12-11 14:21:24 +01:00
|
|
|
if (ppPixelShader != nullptr)
|
|
|
|
*ppPixelShader = m_state.ps.shader.ref();
|
|
|
|
|
2018-01-17 23:49:26 +01:00
|
|
|
if (pNumClassInstances != nullptr)
|
2017-12-11 14:21:24 +01:00
|
|
|
*pNumClassInstances = 0;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::PSGetConstantBuffers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppConstantBuffers) {
|
2017-12-11 14:21:24 +01:00
|
|
|
for (uint32_t i = 0; i < NumBuffers; i++)
|
|
|
|
ppConstantBuffers[i] = m_state.ps.constantBuffers.at(StartSlot + i).ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::PSGetShaderResources(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView** ppShaderResourceViews) {
|
2017-12-11 14:21:24 +01:00
|
|
|
for (uint32_t i = 0; i < NumViews; i++)
|
|
|
|
ppShaderResourceViews[i] = m_state.ps.shaderResources.at(StartSlot + i).ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::PSGetSamplers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState** ppSamplers) {
|
2017-12-11 14:21:24 +01:00
|
|
|
for (uint32_t i = 0; i < NumSamplers; i++)
|
|
|
|
ppSamplers[i] = m_state.ps.samplers.at(StartSlot + i).ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::CSSetShader(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11ComputeShader* pComputeShader,
|
|
|
|
ID3D11ClassInstance* const* ppClassInstances,
|
|
|
|
UINT NumClassInstances) {
|
2017-12-21 17:27:40 +01:00
|
|
|
auto shader = static_cast<D3D11ComputeShader*>(pComputeShader);
|
|
|
|
|
|
|
|
if (NumClassInstances != 0)
|
|
|
|
Logger::err("D3D11DeviceContext::CSSetShader: Class instances not supported");
|
|
|
|
|
|
|
|
if (m_state.cs.shader != shader) {
|
|
|
|
m_state.cs.shader = shader;
|
2018-03-10 10:19:07 +01:00
|
|
|
BindShader(shader, VK_SHADER_STAGE_COMPUTE_BIT);
|
2017-12-21 17:27:40 +01:00
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::CSSetConstantBuffers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers) {
|
2018-03-10 11:16:52 +01:00
|
|
|
this->SetConstantBuffers(
|
2017-12-20 17:37:46 +01:00
|
|
|
DxbcProgramType::ComputeShader,
|
|
|
|
m_state.cs.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::CSSetShaderResources(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView* const* ppShaderResourceViews) {
|
2018-03-10 11:16:52 +01:00
|
|
|
this->SetShaderResources(
|
2017-12-20 17:37:46 +01:00
|
|
|
DxbcProgramType::ComputeShader,
|
|
|
|
m_state.cs.shaderResources,
|
|
|
|
StartSlot, NumViews,
|
|
|
|
ppShaderResourceViews);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::CSSetSamplers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState* const* ppSamplers) {
|
2018-03-10 11:16:52 +01:00
|
|
|
this->SetSamplers(
|
2017-12-20 17:37:46 +01:00
|
|
|
DxbcProgramType::ComputeShader,
|
|
|
|
m_state.cs.samplers,
|
|
|
|
StartSlot, NumSamplers,
|
|
|
|
ppSamplers);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::CSSetUnorderedAccessViews(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumUAVs,
|
|
|
|
ID3D11UnorderedAccessView* const* ppUnorderedAccessViews,
|
|
|
|
const UINT* pUAVInitialCounts) {
|
2018-03-10 11:16:52 +01:00
|
|
|
this->SetUnorderedAccessViews(
|
2017-12-28 19:05:53 +01:00
|
|
|
DxbcProgramType::ComputeShader,
|
|
|
|
m_state.cs.unorderedAccessViews,
|
|
|
|
StartSlot, NumUAVs,
|
|
|
|
ppUnorderedAccessViews);
|
2018-01-11 12:23:55 +01:00
|
|
|
|
|
|
|
if (pUAVInitialCounts != nullptr) {
|
|
|
|
this->InitUnorderedAccessViewCounters(
|
|
|
|
NumUAVs, ppUnorderedAccessViews,
|
|
|
|
pUAVInitialCounts);
|
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::CSGetShader(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11ComputeShader** ppComputeShader,
|
|
|
|
ID3D11ClassInstance** ppClassInstances,
|
|
|
|
UINT* pNumClassInstances) {
|
2017-12-20 17:37:46 +01:00
|
|
|
if (ppComputeShader != nullptr)
|
|
|
|
*ppComputeShader = m_state.cs.shader.ref();
|
|
|
|
|
2018-01-17 23:49:26 +01:00
|
|
|
if (pNumClassInstances != nullptr)
|
2017-12-20 17:37:46 +01:00
|
|
|
*pNumClassInstances = 0;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::CSGetConstantBuffers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppConstantBuffers) {
|
2017-12-20 17:37:46 +01:00
|
|
|
for (uint32_t i = 0; i < NumBuffers; i++)
|
|
|
|
ppConstantBuffers[i] = m_state.cs.constantBuffers.at(StartSlot + i).ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::CSGetShaderResources(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView** ppShaderResourceViews) {
|
2017-12-20 17:37:46 +01:00
|
|
|
for (uint32_t i = 0; i < NumViews; i++)
|
|
|
|
ppShaderResourceViews[i] = m_state.cs.shaderResources.at(StartSlot + i).ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::CSGetSamplers(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState** ppSamplers) {
|
2017-12-20 17:37:46 +01:00
|
|
|
for (uint32_t i = 0; i < NumSamplers; i++)
|
|
|
|
ppSamplers[i] = m_state.cs.samplers.at(StartSlot + i).ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::CSGetUnorderedAccessViews(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumUAVs,
|
|
|
|
ID3D11UnorderedAccessView** ppUnorderedAccessViews) {
|
2018-03-01 07:02:39 +01:00
|
|
|
for (uint32_t i = 0; i < NumUAVs; i++)
|
|
|
|
ppUnorderedAccessViews[i] = m_state.cs.unorderedAccessViews.at(StartSlot + i).ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::OMSetRenderTargets(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT NumViews,
|
|
|
|
ID3D11RenderTargetView* const* ppRenderTargetViews,
|
|
|
|
ID3D11DepthStencilView* pDepthStencilView) {
|
2018-01-13 23:09:03 +01:00
|
|
|
// Optimization: If the number of draw and dispatch calls issued
|
|
|
|
// prior to the previous context flush is above a certain threshold,
|
|
|
|
// submit the current command buffer in order to keep the GPU busy.
|
2018-01-13 23:40:17 +01:00
|
|
|
// This also helps keep the command buffers at a reasonable size.
|
2018-01-13 23:09:03 +01:00
|
|
|
if (m_drawCount >= 500)
|
2018-01-31 16:39:47 +01:00
|
|
|
Flush();
|
2018-01-13 23:09:03 +01:00
|
|
|
|
2017-12-05 12:59:35 +01:00
|
|
|
for (UINT i = 0; i < m_state.om.renderTargetViews.size(); i++) {
|
2017-12-04 13:39:37 +01:00
|
|
|
D3D11RenderTargetView* view = nullptr;
|
2017-11-29 20:19:40 +01:00
|
|
|
|
2017-12-04 13:39:37 +01:00
|
|
|
if ((i < NumViews) && (ppRenderTargetViews[i] != nullptr))
|
|
|
|
view = static_cast<D3D11RenderTargetView*>(ppRenderTargetViews[i]);
|
2017-11-29 20:19:40 +01:00
|
|
|
|
2017-12-05 12:59:35 +01:00
|
|
|
m_state.om.renderTargetViews.at(i) = view;
|
2017-11-29 20:19:40 +01:00
|
|
|
}
|
|
|
|
|
2017-12-09 03:53:42 +01:00
|
|
|
m_state.om.depthStencilView = static_cast<D3D11DepthStencilView*>(pDepthStencilView);
|
|
|
|
|
2018-03-03 22:15:41 +01:00
|
|
|
BindFramebuffer();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT NumRTVs,
|
|
|
|
ID3D11RenderTargetView* const* ppRenderTargetViews,
|
|
|
|
ID3D11DepthStencilView* pDepthStencilView,
|
|
|
|
UINT UAVStartSlot,
|
|
|
|
UINT NumUAVs,
|
|
|
|
ID3D11UnorderedAccessView* const* ppUnorderedAccessViews,
|
2017-11-29 20:19:40 +01:00
|
|
|
const UINT* pUAVInitialCounts) {
|
2018-01-12 15:38:07 +01:00
|
|
|
if (NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL)
|
|
|
|
OMSetRenderTargets(NumRTVs, ppRenderTargetViews, pDepthStencilView);
|
|
|
|
|
|
|
|
if (NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS) {
|
|
|
|
// UAVs are made available to all shader stages in
|
|
|
|
// the graphics pipeline even though this code may
|
|
|
|
// suggest that they are limited to the pixel shader.
|
|
|
|
// This behaviour is only required for FL_11_1.
|
2018-03-10 11:16:52 +01:00
|
|
|
SetUnorderedAccessViews(
|
2018-01-12 15:38:07 +01:00
|
|
|
DxbcProgramType::PixelShader,
|
|
|
|
m_state.ps.unorderedAccessViews,
|
|
|
|
UAVStartSlot, NumUAVs,
|
|
|
|
ppUnorderedAccessViews);
|
|
|
|
|
|
|
|
if (pUAVInitialCounts != nullptr) {
|
|
|
|
InitUnorderedAccessViewCounters(NumUAVs,
|
|
|
|
ppUnorderedAccessViews, pUAVInitialCounts);
|
|
|
|
}
|
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::OMSetBlendState(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11BlendState* pBlendState,
|
|
|
|
const FLOAT BlendFactor[4],
|
|
|
|
UINT SampleMask) {
|
2018-03-10 12:11:17 +01:00
|
|
|
auto blendState = static_cast<D3D11BlendState*>(pBlendState);
|
2017-12-11 14:11:18 +01:00
|
|
|
|
|
|
|
if (m_state.om.cbState != blendState
|
|
|
|
|| m_state.om.sampleMask != SampleMask) {
|
|
|
|
m_state.om.cbState = blendState;
|
|
|
|
m_state.om.sampleMask = SampleMask;
|
|
|
|
|
2018-03-10 11:56:58 +01:00
|
|
|
ApplyBlendState();
|
2017-12-11 14:11:18 +01:00
|
|
|
}
|
|
|
|
|
2018-01-20 15:41:06 +01:00
|
|
|
if (BlendFactor != nullptr) {
|
2018-03-10 11:56:58 +01:00
|
|
|
for (uint32_t i = 0; i < 4; i++)
|
2018-01-20 19:11:42 +01:00
|
|
|
m_state.om.blendFactor[i] = BlendFactor[i];
|
|
|
|
|
2018-03-10 11:56:58 +01:00
|
|
|
ApplyBlendFactor();
|
2017-12-11 14:11:18 +01:00
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::OMSetDepthStencilState(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11DepthStencilState* pDepthStencilState,
|
|
|
|
UINT StencilRef) {
|
2018-03-10 12:11:17 +01:00
|
|
|
auto depthStencilState = static_cast<D3D11DepthStencilState*>(pDepthStencilState);
|
2017-12-11 14:11:18 +01:00
|
|
|
|
|
|
|
if (m_state.om.dsState != depthStencilState) {
|
|
|
|
m_state.om.dsState = depthStencilState;
|
2018-03-10 11:56:58 +01:00
|
|
|
ApplyDepthStencilState();
|
2017-12-11 14:11:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (m_state.om.stencilRef != StencilRef) {
|
|
|
|
m_state.om.stencilRef = StencilRef;
|
2018-03-10 11:56:58 +01:00
|
|
|
ApplyStencilRef();
|
2017-12-11 14:11:18 +01:00
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::OMGetRenderTargets(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT NumViews,
|
|
|
|
ID3D11RenderTargetView** ppRenderTargetViews,
|
|
|
|
ID3D11DepthStencilView** ppDepthStencilView) {
|
2017-11-29 20:19:40 +01:00
|
|
|
if (ppRenderTargetViews != nullptr) {
|
|
|
|
for (UINT i = 0; i < NumViews; i++)
|
2018-03-09 16:47:20 +01:00
|
|
|
ppRenderTargetViews[i] = m_state.om.renderTargetViews[i].ref();
|
2017-11-29 20:19:40 +01:00
|
|
|
}
|
|
|
|
|
2017-12-21 17:14:11 +01:00
|
|
|
if (ppDepthStencilView != nullptr)
|
|
|
|
*ppDepthStencilView = m_state.om.depthStencilView.ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::OMGetRenderTargetsAndUnorderedAccessViews(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT NumRTVs,
|
|
|
|
ID3D11RenderTargetView** ppRenderTargetViews,
|
|
|
|
ID3D11DepthStencilView** ppDepthStencilView,
|
|
|
|
UINT UAVStartSlot,
|
|
|
|
UINT NumUAVs,
|
|
|
|
ID3D11UnorderedAccessView** ppUnorderedAccessViews) {
|
2018-03-09 16:47:20 +01:00
|
|
|
OMGetRenderTargets(NumRTVs, ppRenderTargetViews, ppDepthStencilView);
|
|
|
|
|
|
|
|
if (ppUnorderedAccessViews != nullptr) {
|
|
|
|
for (UINT i = 0; i < NumUAVs; i++)
|
|
|
|
ppUnorderedAccessViews[i] = m_state.ps.unorderedAccessViews[UAVStartSlot + i].ref();
|
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::OMGetBlendState(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11BlendState** ppBlendState,
|
|
|
|
FLOAT BlendFactor[4],
|
|
|
|
UINT* pSampleMask) {
|
2017-12-11 14:21:24 +01:00
|
|
|
if (ppBlendState != nullptr)
|
|
|
|
*ppBlendState = m_state.om.cbState.ref();
|
|
|
|
|
|
|
|
if (BlendFactor != nullptr)
|
|
|
|
std::memcpy(BlendFactor, m_state.om.blendFactor, sizeof(FLOAT) * 4);
|
|
|
|
|
|
|
|
if (pSampleMask != nullptr)
|
|
|
|
*pSampleMask = m_state.om.sampleMask;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::OMGetDepthStencilState(
|
2017-10-11 09:51:48 +02:00
|
|
|
ID3D11DepthStencilState** ppDepthStencilState,
|
|
|
|
UINT* pStencilRef) {
|
2017-12-11 14:21:24 +01:00
|
|
|
if (ppDepthStencilState != nullptr)
|
|
|
|
*ppDepthStencilState = m_state.om.dsState.ref();
|
|
|
|
|
|
|
|
if (pStencilRef != nullptr)
|
|
|
|
*pStencilRef = m_state.om.stencilRef;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::RSSetState(ID3D11RasterizerState* pRasterizerState) {
|
2018-03-10 12:11:17 +01:00
|
|
|
auto rasterizerState = static_cast<D3D11RasterizerState*>(pRasterizerState);
|
2017-12-06 12:11:59 +01:00
|
|
|
|
2017-12-06 13:16:54 +01:00
|
|
|
if (m_state.rs.state != rasterizerState) {
|
|
|
|
m_state.rs.state = rasterizerState;
|
|
|
|
|
2018-03-10 11:56:58 +01:00
|
|
|
// In D3D11, the rasterizer state defines whether the
|
|
|
|
// scissor test is enabled, so we have to update the
|
|
|
|
// scissor rectangles as well.
|
|
|
|
ApplyRasterizerState();
|
|
|
|
ApplyViewportState();
|
2017-12-06 13:16:54 +01:00
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::RSSetViewports(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT NumViewports,
|
|
|
|
const D3D11_VIEWPORT* pViewports) {
|
2017-12-06 12:11:59 +01:00
|
|
|
m_state.rs.numViewports = NumViewports;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < NumViewports; i++)
|
|
|
|
m_state.rs.viewports.at(i) = pViewports[i];
|
|
|
|
|
2018-03-10 11:56:58 +01:00
|
|
|
ApplyViewportState();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::RSSetScissorRects(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT NumRects,
|
|
|
|
const D3D11_RECT* pRects) {
|
2017-12-06 12:11:59 +01:00
|
|
|
m_state.rs.numScissors = NumRects;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < NumRects; i++)
|
|
|
|
m_state.rs.scissors.at(i) = pRects[i];
|
|
|
|
|
|
|
|
if (m_state.rs.state != nullptr) {
|
|
|
|
D3D11_RASTERIZER_DESC rsDesc;
|
|
|
|
m_state.rs.state->GetDesc(&rsDesc);
|
|
|
|
|
|
|
|
if (rsDesc.ScissorEnable)
|
2018-03-10 11:56:58 +01:00
|
|
|
ApplyViewportState();
|
2017-12-06 12:11:59 +01:00
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::RSGetState(ID3D11RasterizerState** ppRasterizerState) {
|
2017-12-11 14:21:24 +01:00
|
|
|
if (ppRasterizerState != nullptr)
|
|
|
|
*ppRasterizerState = m_state.rs.state.ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::RSGetViewports(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT* pNumViewports,
|
|
|
|
D3D11_VIEWPORT* pViewports) {
|
2017-12-06 12:11:59 +01:00
|
|
|
if (pViewports != nullptr) {
|
|
|
|
for (uint32_t i = 0; i < *pNumViewports; i++) {
|
|
|
|
if (i < m_state.rs.numViewports) {
|
|
|
|
pViewports[i] = m_state.rs.viewports.at(i);
|
|
|
|
} else {
|
|
|
|
pViewports[i].TopLeftX = 0.0f;
|
|
|
|
pViewports[i].TopLeftY = 0.0f;
|
|
|
|
pViewports[i].Width = 0.0f;
|
|
|
|
pViewports[i].Height = 0.0f;
|
|
|
|
pViewports[i].MinDepth = 0.0f;
|
|
|
|
pViewports[i].MaxDepth = 0.0f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*pNumViewports = m_state.rs.numViewports;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::RSGetScissorRects(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT* pNumRects,
|
|
|
|
D3D11_RECT* pRects) {
|
2017-12-06 12:11:59 +01:00
|
|
|
if (pRects != nullptr) {
|
|
|
|
for (uint32_t i = 0; i < *pNumRects; i++) {
|
|
|
|
if (i < m_state.rs.numScissors) {
|
|
|
|
pRects[i] = m_state.rs.scissors.at(i);
|
|
|
|
} else {
|
|
|
|
pRects[i].left = 0;
|
|
|
|
pRects[i].top = 0;
|
|
|
|
pRects[i].right = 0;
|
|
|
|
pRects[i].bottom = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*pNumRects = m_state.rs.numScissors;
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::SOSetTargets(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppSOTargets,
|
|
|
|
const UINT* pOffsets) {
|
2018-03-07 15:32:19 +01:00
|
|
|
// TODO implement properly, including pOffsets
|
|
|
|
for (uint32_t i = 0; i < D3D11_SO_STREAM_COUNT; i++) {
|
|
|
|
m_state.so.targets[i] = (ppSOTargets != nullptr && i < NumBuffers)
|
|
|
|
? static_cast<D3D11Buffer*>(ppSOTargets[i])
|
|
|
|
: nullptr;
|
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeviceContext::SOGetTargets(
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppSOTargets) {
|
2018-03-07 15:32:19 +01:00
|
|
|
for (uint32_t i = 0; i < NumBuffers; i++)
|
|
|
|
ppSOTargets[i] = m_state.so.targets[i].ref();
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
2017-12-06 12:11:59 +01:00
|
|
|
|
2018-03-10 11:44:27 +01:00
|
|
|
void D3D11DeviceContext::ApplyInputLayout() {
|
|
|
|
if (m_state.ia.inputLayout != nullptr) {
|
|
|
|
EmitCs([cInputLayout = m_state.ia.inputLayout] (DxvkContext* ctx) {
|
|
|
|
cInputLayout->BindToContext(ctx);
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
EmitCs([] (DxvkContext* ctx) {
|
|
|
|
ctx->setInputLayout(0, nullptr, 0, nullptr);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void D3D11DeviceContext::ApplyPrimitiveTopology() {
|
|
|
|
if (m_state.ia.primitiveTopology == D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED)
|
|
|
|
return;
|
|
|
|
|
|
|
|
const DxvkInputAssemblyState iaState =
|
|
|
|
[Topology = m_state.ia.primitiveTopology] () -> DxvkInputAssemblyState {
|
|
|
|
if (Topology >= D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST
|
|
|
|
&& Topology <= D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST) {
|
|
|
|
// Tessellation patch. The number of control points per
|
|
|
|
// patch can be inferred from the enum value in D3D11.
|
|
|
|
return { VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE,
|
|
|
|
uint32_t(Topology - D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + 1) };
|
|
|
|
} else {
|
|
|
|
switch (Topology) {
|
|
|
|
case D3D11_PRIMITIVE_TOPOLOGY_POINTLIST:
|
|
|
|
return { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, VK_FALSE, 0 };
|
|
|
|
|
|
|
|
case D3D11_PRIMITIVE_TOPOLOGY_LINELIST:
|
|
|
|
return { VK_PRIMITIVE_TOPOLOGY_LINE_LIST, VK_FALSE, 0 };
|
|
|
|
|
|
|
|
case D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP:
|
|
|
|
return { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, VK_TRUE, 0 };
|
|
|
|
|
|
|
|
case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST:
|
|
|
|
return { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_FALSE, 0 };
|
|
|
|
|
|
|
|
case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP:
|
|
|
|
return { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, VK_TRUE, 0 };
|
|
|
|
|
|
|
|
case D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ:
|
|
|
|
return { VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, VK_FALSE, 0 };
|
|
|
|
|
|
|
|
case D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ:
|
|
|
|
return { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY, VK_TRUE, 0 };
|
|
|
|
|
|
|
|
case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ:
|
|
|
|
return { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY, VK_FALSE, 0 };
|
|
|
|
|
|
|
|
case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ:
|
|
|
|
return { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY, VK_TRUE, 0 };
|
|
|
|
|
|
|
|
default:
|
|
|
|
Logger::err(str::format("D3D11: Invalid primitive topology: ", Topology));
|
|
|
|
return { };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}();
|
|
|
|
|
|
|
|
EmitCs([iaState] (DxvkContext* ctx) {
|
|
|
|
ctx->setInputAssemblyState(iaState);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-10 11:56:58 +01:00
|
|
|
void D3D11DeviceContext::ApplyBlendState() {
|
|
|
|
EmitCs([
|
|
|
|
cBlendState = m_state.om.cbState != nullptr
|
|
|
|
? m_state.om.cbState
|
|
|
|
: m_defaultBlendState,
|
|
|
|
cSampleMask = m_state.om.sampleMask
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
cBlendState->BindToContext(ctx, cSampleMask);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void D3D11DeviceContext::ApplyBlendFactor() {
|
|
|
|
EmitCs([
|
|
|
|
cBlendConstants = DxvkBlendConstants {
|
|
|
|
m_state.om.blendFactor[0], m_state.om.blendFactor[1],
|
|
|
|
m_state.om.blendFactor[2], m_state.om.blendFactor[3] }
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->setBlendConstants(cBlendConstants);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void D3D11DeviceContext::ApplyDepthStencilState() {
|
|
|
|
EmitCs([
|
|
|
|
cDepthStencilState = m_state.om.dsState != nullptr
|
|
|
|
? m_state.om.dsState
|
|
|
|
: m_defaultDepthStencilState
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
cDepthStencilState->BindToContext(ctx);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void D3D11DeviceContext::ApplyStencilRef() {
|
|
|
|
EmitCs([
|
|
|
|
cStencilRef = m_state.om.stencilRef
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->setStencilReference(cStencilRef);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void D3D11DeviceContext::ApplyRasterizerState() {
|
|
|
|
EmitCs([
|
|
|
|
cRasterizerState = m_state.rs.state != nullptr
|
|
|
|
? m_state.rs.state
|
|
|
|
: m_defaultRasterizerState
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
cRasterizerState->BindToContext(ctx);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-10 11:44:27 +01:00
|
|
|
void D3D11DeviceContext::ApplyViewportState() {
|
|
|
|
// We cannot set less than one viewport in Vulkan, and
|
|
|
|
// rendering with no active viewport is illegal anyway.
|
|
|
|
if (m_state.rs.numViewports == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
std::array<VkViewport, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE> viewports;
|
|
|
|
std::array<VkRect2D, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE> scissors;
|
|
|
|
|
|
|
|
// D3D11's coordinate system has its origin in the bottom left,
|
|
|
|
// but the viewport coordinates are aligned to the top-left
|
|
|
|
// corner so we can get away with flipping the viewport.
|
|
|
|
for (uint32_t i = 0; i < m_state.rs.numViewports; i++) {
|
|
|
|
const D3D11_VIEWPORT& vp = m_state.rs.viewports.at(i);
|
|
|
|
|
|
|
|
viewports.at(i) = VkViewport {
|
|
|
|
vp.TopLeftX, vp.Height + vp.TopLeftY,
|
|
|
|
vp.Width, -vp.Height,
|
|
|
|
vp.MinDepth, vp.MaxDepth,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
// Scissor rectangles. Vulkan does not provide an easy way
|
|
|
|
// to disable the scissor test, so we'll have to set scissor
|
|
|
|
// rects that are at least as large as the framebuffer.
|
|
|
|
bool enableScissorTest = false;
|
|
|
|
|
|
|
|
if (m_state.rs.state != nullptr) {
|
|
|
|
D3D11_RASTERIZER_DESC rsDesc;
|
|
|
|
m_state.rs.state->GetDesc(&rsDesc);
|
|
|
|
enableScissorTest = rsDesc.ScissorEnable;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < m_state.rs.numViewports; i++) {
|
|
|
|
// TODO D3D11 docs aren't clear about what should happen
|
|
|
|
// when there are undefined scissor rects for a viewport.
|
|
|
|
// Figure out what it does on Windows.
|
|
|
|
if (enableScissorTest && (i < m_state.rs.numScissors)) {
|
|
|
|
const D3D11_RECT& sr = m_state.rs.scissors.at(i);
|
|
|
|
|
|
|
|
scissors.at(i) = VkRect2D {
|
|
|
|
VkOffset2D { sr.left, sr.top },
|
|
|
|
VkExtent2D {
|
|
|
|
static_cast<uint32_t>(sr.right - sr.left),
|
|
|
|
static_cast<uint32_t>(sr.bottom - sr.top) } };
|
|
|
|
} else {
|
|
|
|
scissors.at(i) = VkRect2D {
|
|
|
|
VkOffset2D { 0, 0 },
|
|
|
|
VkExtent2D {
|
|
|
|
D3D11_VIEWPORT_BOUNDS_MAX,
|
|
|
|
D3D11_VIEWPORT_BOUNDS_MAX } };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EmitCs([
|
|
|
|
cViewportCount = m_state.rs.numViewports,
|
|
|
|
cViewports = viewports,
|
|
|
|
cScissors = scissors
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->setViewports(
|
|
|
|
cViewportCount,
|
|
|
|
cViewports.data(),
|
|
|
|
cScissors.data());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-03 22:15:41 +01:00
|
|
|
void D3D11DeviceContext::BindFramebuffer() {
|
|
|
|
// NOTE According to the Microsoft docs, we are supposed to
|
|
|
|
// unbind overlapping shader resource views. Since this comes
|
|
|
|
// with a large performance penalty we'll ignore this until an
|
|
|
|
// application actually relies on this behaviour.
|
|
|
|
DxvkRenderTargets attachments;
|
|
|
|
|
|
|
|
// D3D11 doesn't have the concept of a framebuffer object,
|
|
|
|
// so we'll just create a new one every time the render
|
|
|
|
// target bindings are updated. Set up the attachments.
|
|
|
|
for (UINT i = 0; i < m_state.om.renderTargetViews.size(); i++) {
|
|
|
|
if (m_state.om.renderTargetViews.at(i) != nullptr) {
|
|
|
|
attachments.setColorTarget(i,
|
|
|
|
m_state.om.renderTargetViews.at(i)->GetImageView(),
|
|
|
|
m_state.om.renderTargetViews.at(i)->GetRenderLayout());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_state.om.depthStencilView != nullptr) {
|
|
|
|
attachments.setDepthTarget(
|
|
|
|
m_state.om.depthStencilView->GetImageView(),
|
|
|
|
m_state.om.depthStencilView->GetRenderLayout());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create and bind the framebuffer object to the context
|
|
|
|
EmitCs([attachments, dev = m_device] (DxvkContext* ctx) {
|
|
|
|
Rc<DxvkFramebuffer> framebuffer = nullptr;
|
|
|
|
if (attachments.hasAttachments())
|
|
|
|
framebuffer = dev->createFramebuffer(attachments);
|
|
|
|
ctx->bindFramebuffer(framebuffer);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-10 10:39:07 +01:00
|
|
|
void D3D11DeviceContext::BindVertexBuffer(
|
|
|
|
UINT Slot,
|
|
|
|
D3D11Buffer* pBuffer,
|
|
|
|
UINT Offset,
|
|
|
|
UINT Stride) {
|
|
|
|
EmitCs([
|
|
|
|
cSlotId = Slot,
|
|
|
|
cBufferSlice = pBuffer != nullptr ? pBuffer->GetBufferSlice(Offset) : DxvkBufferSlice(),
|
|
|
|
cStride = pBuffer != nullptr ? Stride : 0
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->bindVertexBuffer(cSlotId, cBufferSlice, cStride);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void D3D11DeviceContext::BindIndexBuffer(
|
|
|
|
D3D11Buffer* pBuffer,
|
|
|
|
UINT Offset,
|
|
|
|
DXGI_FORMAT Format) {
|
|
|
|
// As in Vulkan, the index format can be either a 32-bit
|
|
|
|
// or 16-bit unsigned integer, no other formats are allowed.
|
2018-03-10 12:11:17 +01:00
|
|
|
VkIndexType indexType = VK_INDEX_TYPE_UINT32;
|
2018-03-10 10:39:07 +01:00
|
|
|
|
2018-03-10 12:11:17 +01:00
|
|
|
if (pBuffer != nullptr) {
|
|
|
|
switch (Format) {
|
|
|
|
case DXGI_FORMAT_R16_UINT: indexType = VK_INDEX_TYPE_UINT16; break;
|
|
|
|
case DXGI_FORMAT_R32_UINT: indexType = VK_INDEX_TYPE_UINT32; break;
|
|
|
|
default: Logger::err(str::format("D3D11: Invalid index format: ", Format));
|
|
|
|
}
|
2018-03-10 10:39:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
EmitCs([
|
|
|
|
cBufferSlice = pBuffer != nullptr ? pBuffer->GetBufferSlice(Offset) : DxvkBufferSlice(),
|
|
|
|
cIndexType = indexType
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->bindIndexBuffer(cBufferSlice, cIndexType);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-10 11:16:52 +01:00
|
|
|
void D3D11DeviceContext::BindConstantBuffer(
|
|
|
|
UINT Slot,
|
|
|
|
D3D11Buffer* pBuffer) {
|
|
|
|
EmitCs([
|
|
|
|
cSlotId = Slot,
|
|
|
|
cBufferSlice = pBuffer != nullptr ? pBuffer->GetBufferSlice() : DxvkBufferSlice()
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->bindResourceBuffer(cSlotId, cBufferSlice);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void D3D11DeviceContext::BindSampler(
|
|
|
|
UINT Slot,
|
|
|
|
D3D11SamplerState* pSampler) {
|
|
|
|
EmitCs([
|
|
|
|
cSlotId = Slot,
|
|
|
|
cSampler = pSampler != nullptr ? pSampler->GetDXVKSampler() : nullptr
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->bindResourceSampler(cSlotId, cSampler);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void D3D11DeviceContext::BindShaderResource(
|
|
|
|
UINT Slot,
|
|
|
|
D3D11ShaderResourceView* pResource) {
|
|
|
|
EmitCs([
|
|
|
|
cSlotId = Slot,
|
|
|
|
cImageView = pResource != nullptr ? pResource->GetImageView() : nullptr,
|
|
|
|
cBufferView = pResource != nullptr ? pResource->GetBufferView() : nullptr
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->bindResourceView(cSlotId, cImageView, cBufferView);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void D3D11DeviceContext::BindUnorderedAccessView(
|
|
|
|
UINT UavSlot,
|
|
|
|
UINT CtrSlot,
|
|
|
|
D3D11UnorderedAccessView* pUav) {
|
|
|
|
EmitCs([
|
|
|
|
cUavSlotId = UavSlot,
|
|
|
|
cCtrSlotId = CtrSlot,
|
|
|
|
cImageView = pUav != nullptr ? pUav->GetImageView() : nullptr,
|
|
|
|
cBufferView = pUav != nullptr ? pUav->GetBufferView() : nullptr,
|
|
|
|
cCounterSlice = pUav != nullptr ? pUav->GetCounterSlice() : DxvkBufferSlice()
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->bindResourceView (cUavSlotId, cImageView, cBufferView);
|
|
|
|
ctx->bindResourceBuffer (cCtrSlotId, cCounterSlice);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void D3D11DeviceContext::SetConstantBuffers(
|
2017-12-08 22:30:41 +01:00
|
|
|
DxbcProgramType ShaderStage,
|
2017-12-20 17:37:46 +01:00
|
|
|
D3D11ConstantBufferBindings& Bindings,
|
2017-12-08 19:39:33 +01:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers) {
|
2017-12-20 17:37:46 +01:00
|
|
|
const uint32_t slotId = computeResourceSlotId(
|
|
|
|
ShaderStage, DxbcBindingType::ConstantBuffer,
|
|
|
|
StartSlot);
|
|
|
|
|
2017-12-08 19:39:33 +01:00
|
|
|
for (uint32_t i = 0; i < NumBuffers; i++) {
|
2017-12-20 17:37:46 +01:00
|
|
|
auto newBuffer = static_cast<D3D11Buffer*>(ppConstantBuffers[i]);
|
2017-12-08 19:39:33 +01:00
|
|
|
|
2017-12-20 17:37:46 +01:00
|
|
|
if (Bindings[StartSlot + i] != newBuffer) {
|
|
|
|
Bindings[StartSlot + i] = newBuffer;
|
2018-03-10 11:16:52 +01:00
|
|
|
BindConstantBuffer(slotId + i, newBuffer);
|
2017-12-08 19:39:33 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-10 11:16:52 +01:00
|
|
|
void D3D11DeviceContext::SetSamplers(
|
2017-12-09 21:17:26 +01:00
|
|
|
DxbcProgramType ShaderStage,
|
2017-12-20 17:37:46 +01:00
|
|
|
D3D11SamplerBindings& Bindings,
|
2017-12-09 21:17:26 +01:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState* const* ppSamplers) {
|
2017-12-20 17:37:46 +01:00
|
|
|
const uint32_t slotId = computeResourceSlotId(
|
|
|
|
ShaderStage, DxbcBindingType::ImageSampler,
|
|
|
|
StartSlot);
|
|
|
|
|
2017-12-09 21:17:26 +01:00
|
|
|
for (uint32_t i = 0; i < NumSamplers; i++) {
|
2017-12-20 17:37:46 +01:00
|
|
|
auto sampler = static_cast<D3D11SamplerState*>(ppSamplers[i]);
|
2017-12-09 21:17:26 +01:00
|
|
|
|
2017-12-20 17:37:46 +01:00
|
|
|
if (Bindings[StartSlot + i] != sampler) {
|
|
|
|
Bindings[StartSlot + i] = sampler;
|
2018-03-10 11:16:52 +01:00
|
|
|
BindSampler(slotId + i, sampler);
|
2017-12-09 21:17:26 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-10 11:16:52 +01:00
|
|
|
void D3D11DeviceContext::SetShaderResources(
|
2017-12-10 01:56:07 +01:00
|
|
|
DxbcProgramType ShaderStage,
|
2017-12-20 17:37:46 +01:00
|
|
|
D3D11ShaderResourceBindings& Bindings,
|
2017-12-10 01:56:07 +01:00
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumResources,
|
|
|
|
ID3D11ShaderResourceView* const* ppResources) {
|
2017-12-20 17:37:46 +01:00
|
|
|
const uint32_t slotId = computeResourceSlotId(
|
|
|
|
ShaderStage, DxbcBindingType::ShaderResource,
|
|
|
|
StartSlot);
|
|
|
|
|
2017-12-10 01:56:07 +01:00
|
|
|
for (uint32_t i = 0; i < NumResources; i++) {
|
2017-12-20 17:37:46 +01:00
|
|
|
auto resView = static_cast<D3D11ShaderResourceView*>(ppResources[i]);
|
2017-12-10 01:56:07 +01:00
|
|
|
|
2017-12-20 17:37:46 +01:00
|
|
|
if (Bindings[StartSlot + i] != resView) {
|
|
|
|
Bindings[StartSlot + i] = resView;
|
2018-03-10 11:16:52 +01:00
|
|
|
BindShaderResource(slotId + i, resView);
|
2017-12-10 01:56:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-10 11:16:52 +01:00
|
|
|
void D3D11DeviceContext::SetUnorderedAccessViews(
|
2017-12-28 19:05:53 +01:00
|
|
|
DxbcProgramType ShaderStage,
|
|
|
|
D3D11UnorderedAccessBindings& Bindings,
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumUAVs,
|
|
|
|
ID3D11UnorderedAccessView* const* ppUnorderedAccessViews) {
|
2018-01-11 17:12:39 +01:00
|
|
|
const uint32_t uavSlotId = computeResourceSlotId(
|
2017-12-28 19:05:53 +01:00
|
|
|
ShaderStage, DxbcBindingType::UnorderedAccessView,
|
|
|
|
StartSlot);
|
|
|
|
|
2018-01-11 17:12:39 +01:00
|
|
|
const uint32_t ctrSlotId = computeResourceSlotId(
|
|
|
|
ShaderStage, DxbcBindingType::UavCounter,
|
|
|
|
StartSlot);
|
|
|
|
|
2017-12-28 19:05:53 +01:00
|
|
|
for (uint32_t i = 0; i < NumUAVs; i++) {
|
|
|
|
auto uav = static_cast<D3D11UnorderedAccessView*>(ppUnorderedAccessViews[i]);
|
|
|
|
|
|
|
|
if (Bindings[StartSlot + i] != uav) {
|
|
|
|
Bindings[StartSlot + i] = uav;
|
2018-03-10 11:16:52 +01:00
|
|
|
BindUnorderedAccessView(uavSlotId + i, ctrSlotId + i, uav);
|
2017-12-28 19:05:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-01-11 12:23:55 +01:00
|
|
|
void D3D11DeviceContext::InitUnorderedAccessViewCounters(
|
|
|
|
UINT NumUAVs,
|
|
|
|
ID3D11UnorderedAccessView* const* ppUnorderedAccessViews,
|
|
|
|
const UINT* pUAVInitialCounts) {
|
|
|
|
for (uint32_t i = 0; i < NumUAVs; i++) {
|
|
|
|
auto uav = static_cast<D3D11UnorderedAccessView*>(ppUnorderedAccessViews[i]);
|
|
|
|
|
|
|
|
if (uav != nullptr) {
|
|
|
|
const DxvkBufferSlice counterSlice = uav->GetCounterSlice();
|
|
|
|
const D3D11UavCounter counterValue = { pUAVInitialCounts[i] };
|
|
|
|
|
2018-01-18 18:33:13 +01:00
|
|
|
if (counterSlice.defined()
|
2018-01-11 17:12:39 +01:00
|
|
|
&& counterValue.atomicCtr != 0xFFFFFFFFu) {
|
2018-01-20 18:54:37 +01:00
|
|
|
EmitCs([counterSlice, counterValue] (DxvkContext* ctx) {
|
|
|
|
ctx->updateBuffer(
|
|
|
|
counterSlice.buffer(),
|
|
|
|
counterSlice.offset(),
|
|
|
|
counterSlice.length(),
|
|
|
|
&counterValue);
|
|
|
|
});
|
2018-01-11 12:23:55 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-03 20:59:17 +01:00
|
|
|
void D3D11DeviceContext::RestoreState() {
|
2018-03-03 22:15:41 +01:00
|
|
|
BindFramebuffer();
|
2018-03-10 10:19:07 +01:00
|
|
|
|
|
|
|
BindShader(m_state.vs.shader.ptr(), VK_SHADER_STAGE_VERTEX_BIT);
|
|
|
|
BindShader(m_state.hs.shader.ptr(), VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
|
|
|
|
BindShader(m_state.ds.shader.ptr(), VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
|
|
|
|
BindShader(m_state.gs.shader.ptr(), VK_SHADER_STAGE_GEOMETRY_BIT);
|
|
|
|
BindShader(m_state.ps.shader.ptr(), VK_SHADER_STAGE_FRAGMENT_BIT);
|
|
|
|
BindShader(m_state.cs.shader.ptr(), VK_SHADER_STAGE_COMPUTE_BIT);
|
2018-03-10 10:39:07 +01:00
|
|
|
|
2018-03-10 11:44:27 +01:00
|
|
|
ApplyInputLayout();
|
|
|
|
ApplyPrimitiveTopology();
|
2018-03-10 11:56:58 +01:00
|
|
|
ApplyBlendState();
|
|
|
|
ApplyBlendFactor();
|
|
|
|
ApplyDepthStencilState();
|
|
|
|
ApplyStencilRef();
|
|
|
|
ApplyRasterizerState();
|
2018-03-10 11:44:27 +01:00
|
|
|
ApplyViewportState();
|
|
|
|
|
2018-03-10 10:39:07 +01:00
|
|
|
BindIndexBuffer(
|
|
|
|
m_state.ia.indexBuffer.buffer.ptr(),
|
|
|
|
m_state.ia.indexBuffer.offset,
|
|
|
|
m_state.ia.indexBuffer.format);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < m_state.ia.vertexBuffers.size(); i++) {
|
|
|
|
BindVertexBuffer(i,
|
|
|
|
m_state.ia.vertexBuffers[i].buffer.ptr(),
|
|
|
|
m_state.ia.vertexBuffers[i].offset,
|
|
|
|
m_state.ia.vertexBuffers[i].stride);
|
|
|
|
}
|
2018-03-10 11:30:32 +01:00
|
|
|
|
|
|
|
RestoreConstantBuffers(DxbcProgramType::VertexShader, m_state.vs.constantBuffers);
|
|
|
|
RestoreConstantBuffers(DxbcProgramType::HullShader, m_state.hs.constantBuffers);
|
|
|
|
RestoreConstantBuffers(DxbcProgramType::DomainShader, m_state.ds.constantBuffers);
|
|
|
|
RestoreConstantBuffers(DxbcProgramType::GeometryShader, m_state.gs.constantBuffers);
|
|
|
|
RestoreConstantBuffers(DxbcProgramType::PixelShader, m_state.ps.constantBuffers);
|
|
|
|
RestoreConstantBuffers(DxbcProgramType::ComputeShader, m_state.cs.constantBuffers);
|
|
|
|
|
|
|
|
RestoreSamplers(DxbcProgramType::VertexShader, m_state.vs.samplers);
|
|
|
|
RestoreSamplers(DxbcProgramType::HullShader, m_state.hs.samplers);
|
|
|
|
RestoreSamplers(DxbcProgramType::DomainShader, m_state.ds.samplers);
|
|
|
|
RestoreSamplers(DxbcProgramType::GeometryShader, m_state.gs.samplers);
|
|
|
|
RestoreSamplers(DxbcProgramType::PixelShader, m_state.ps.samplers);
|
|
|
|
RestoreSamplers(DxbcProgramType::ComputeShader, m_state.cs.samplers);
|
|
|
|
|
|
|
|
RestoreShaderResources(DxbcProgramType::VertexShader, m_state.vs.shaderResources);
|
|
|
|
RestoreShaderResources(DxbcProgramType::HullShader, m_state.hs.shaderResources);
|
|
|
|
RestoreShaderResources(DxbcProgramType::DomainShader, m_state.ds.shaderResources);
|
|
|
|
RestoreShaderResources(DxbcProgramType::GeometryShader, m_state.gs.shaderResources);
|
|
|
|
RestoreShaderResources(DxbcProgramType::PixelShader, m_state.ps.shaderResources);
|
|
|
|
RestoreShaderResources(DxbcProgramType::ComputeShader, m_state.cs.shaderResources);
|
|
|
|
|
|
|
|
RestoreUnorderedAccessViews(DxbcProgramType::PixelShader, m_state.ps.unorderedAccessViews);
|
|
|
|
RestoreUnorderedAccessViews(DxbcProgramType::ComputeShader, m_state.cs.unorderedAccessViews);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void D3D11DeviceContext::RestoreConstantBuffers(
|
|
|
|
DxbcProgramType Stage,
|
|
|
|
D3D11ConstantBufferBindings& Bindings) {
|
|
|
|
const uint32_t slotId = computeResourceSlotId(
|
|
|
|
Stage, DxbcBindingType::ConstantBuffer, 0);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < Bindings.size(); i++)
|
|
|
|
BindConstantBuffer(slotId + i, Bindings[i].ptr());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void D3D11DeviceContext::RestoreSamplers(
|
|
|
|
DxbcProgramType Stage,
|
|
|
|
D3D11SamplerBindings& Bindings) {
|
|
|
|
const uint32_t slotId = computeResourceSlotId(
|
|
|
|
Stage, DxbcBindingType::ImageSampler, 0);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < Bindings.size(); i++)
|
|
|
|
BindSampler(slotId + i, Bindings[i].ptr());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void D3D11DeviceContext::RestoreShaderResources(
|
|
|
|
DxbcProgramType Stage,
|
|
|
|
D3D11ShaderResourceBindings& Bindings) {
|
|
|
|
const uint32_t slotId = computeResourceSlotId(
|
|
|
|
Stage, DxbcBindingType::ShaderResource, 0);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < Bindings.size(); i++)
|
|
|
|
BindShaderResource(slotId + i, Bindings[i].ptr());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void D3D11DeviceContext::RestoreUnorderedAccessViews(
|
|
|
|
DxbcProgramType Stage,
|
|
|
|
D3D11UnorderedAccessBindings& Bindings) {
|
|
|
|
const uint32_t uavSlotId = computeResourceSlotId(
|
|
|
|
Stage, DxbcBindingType::UnorderedAccessView, 0);
|
|
|
|
|
|
|
|
const uint32_t ctrSlotId = computeResourceSlotId(
|
|
|
|
Stage, DxbcBindingType::UavCounter, 0);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < Bindings.size(); i++) {
|
|
|
|
BindUnorderedAccessView(
|
|
|
|
uavSlotId + i, ctrSlotId + i,
|
|
|
|
Bindings[i].ptr());
|
|
|
|
}
|
2018-03-03 20:59:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-01-23 16:43:55 +01:00
|
|
|
DxvkDataSlice D3D11DeviceContext::AllocUpdateBufferSlice(size_t Size) {
|
|
|
|
constexpr size_t UpdateBufferSize = 4 * 1024 * 1024;
|
|
|
|
|
|
|
|
if (Size >= UpdateBufferSize) {
|
|
|
|
Rc<DxvkDataBuffer> buffer = new DxvkDataBuffer(Size);
|
|
|
|
return buffer->alloc(Size);
|
|
|
|
} else {
|
|
|
|
if (m_updateBuffer == nullptr)
|
|
|
|
m_updateBuffer = new DxvkDataBuffer(Size);
|
|
|
|
|
|
|
|
DxvkDataSlice slice = m_updateBuffer->alloc(Size);
|
|
|
|
|
|
|
|
if (slice.ptr() == nullptr) {
|
|
|
|
m_updateBuffer = new DxvkDataBuffer(Size);
|
|
|
|
slice = m_updateBuffer->alloc(Size);
|
|
|
|
}
|
|
|
|
|
|
|
|
return slice;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|