[d3d11] Implemented constant buffer binding

This commit is contained in:
Philip Rebohle 2017-12-08 19:39:33 +01:00
parent e872448ca3
commit 0610296248
11 changed files with 178 additions and 78 deletions

View File

@ -113,7 +113,7 @@ namespace dxvk {
// this->IASetIndexBuffer(nullptr, DXGI_FORMAT_UNKNOWN, 0);
this->VSSetShader(nullptr, nullptr, 0);
// this->VSSetConstantBuffers(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, nullptr);
this->VSSetConstantBuffers(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, nullptr);
// this->VSSetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, nullptr);
// this->VSSetSamplers (0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, nullptr);
@ -133,7 +133,7 @@ namespace dxvk {
// this->GSSetSamplers (0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, nullptr);
this->PSSetShader(nullptr, nullptr, 0);
// this->PSSetConstantBuffers(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, nullptr);
this->PSSetConstantBuffers(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, nullptr);
// this->PSSetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, nullptr);
// this->PSSetSamplers (0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, nullptr);
@ -360,7 +360,32 @@ namespace dxvk {
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch) {
Logger::err("D3D11DeviceContext::UpdateSubresource: Not implemented");
// We need a different code path for buffers
D3D11_RESOURCE_DIMENSION resourceType;
pDstResource->GetType(&resourceType);
if (resourceType == D3D11_RESOURCE_DIMENSION_BUFFER) {
Com<IDXGIBufferResourcePrivate> bufferResource;
pDstResource->QueryInterface(
__uuidof(IDXGIBufferResourcePrivate),
reinterpret_cast<void**>(&bufferResource));
VkDeviceSize offset = 0;
VkDeviceSize size = VK_WHOLE_SIZE;
if (pDstBox != nullptr) {
offset = pDstBox->left;
size = pDstBox->right - pDstBox->left;
}
m_context->updateBuffer(
bufferResource->GetDXVKBuffer(),
offset, size, pSrcData);
} else {
Logger::err("D3D11DeviceContext::UpdateSubresource: Images not yet supported");
}
}
@ -613,16 +638,10 @@ namespace dxvk {
switch (binding.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(
"D3D11DeviceContext::IASetIndexBuffer: Invalid index format: ",
binding.format));
}
m_context->bindIndexBuffer(
dxvkBinding, indexType);
}
@ -676,7 +695,11 @@ namespace dxvk {
UINT StartSlot,
UINT NumBuffers,
ID3D11Buffer* const* ppConstantBuffers) {
Logger::err("D3D11DeviceContext::VSSetConstantBuffers: Not implemented");
this->BindConstantBuffers(
D3D11ShaderStage::VertexShader,
&m_state.vs.constantBuffers,
StartSlot, NumBuffers,
ppConstantBuffers);
}
@ -942,7 +965,11 @@ namespace dxvk {
UINT StartSlot,
UINT NumBuffers,
ID3D11Buffer* const* ppConstantBuffers) {
Logger::err("D3D11DeviceContext::PSSetConstantBuffers: Not implemented");
this->BindConstantBuffers(
D3D11ShaderStage::PixelShader,
&m_state.vs.constantBuffers,
StartSlot, NumBuffers,
ppConstantBuffers);
}
@ -1301,6 +1328,38 @@ namespace dxvk {
}
void D3D11DeviceContext::BindConstantBuffers(
D3D11ShaderStage ShaderStage,
D3D11ConstantBufferBindings* pBindings,
UINT StartSlot,
UINT NumBuffers,
ID3D11Buffer* const* ppConstantBuffers) {
for (uint32_t i = 0; i < NumBuffers; i++) {
D3D11Buffer* buffer = nullptr;
if (ppConstantBuffers != nullptr)
buffer = static_cast<D3D11Buffer*>(ppConstantBuffers[i]);
if (pBindings->at(StartSlot + i) != buffer) {
pBindings->at(StartSlot + i) = buffer;
DxvkBufferBinding dxvkBinding;
if (buffer != nullptr) {
dxvkBinding = DxvkBufferBinding(
buffer->GetDXVKBuffer(),
0, VK_WHOLE_SIZE);
}
// TODO compute actual slot index
m_context->bindResourceBuffer(
VK_PIPELINE_BIND_POINT_GRAPHICS, 0,
dxvkBinding);
}
}
}
void D3D11DeviceContext::ApplyViewportState() {
// We cannot set less than one viewport in Vulkan, and
// rendering with no active viewport is illegal anyway.

View File

@ -554,6 +554,13 @@ namespace dxvk {
D3D11ContextState m_state;
void BindConstantBuffers(
D3D11ShaderStage ShaderStage,
D3D11ConstantBufferBindings* pBindings,
UINT StartSlot,
UINT NumBuffers,
ID3D11Buffer* const* ppConstantBuffers);
void ApplyViewportState();
void SetupIAStateObjects();

View File

@ -10,54 +10,51 @@
namespace dxvk {
struct D3D11ComputePipelineBindings {
std::array<Com<D3D11Buffer>, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT> constantBuffers;
// std::array<Com<D3D11ShaderResourceView>, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> shaderResourceViews;
// std::array<Com<D3D11UnorderedAccessView>, D3D11_1_UAV_SLOT_COUNT> uniformAccessViews;
// std::array<Com<D3D11SamplerState>, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT> samplers;
};
struct D3D11GraphicsPipelineBindings {
std::array<Com<D3D11Buffer>, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT> constantBuffers;
// std::array<Com<D3D11ShaderResourceView>, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> shaderResourceViews;
// std::array<Com<D3D11SamplerState>, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT> samplers;
enum class D3D11ShaderStage {
VertexShader = 0,
HullShader = 1,
DomainShader = 2,
GeometryShader = 3,
PixelShader = 4,
ComputeShader = 5,
};
using D3D11ConstantBufferBindings = std::array<
Com<D3D11Buffer>, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT>;
struct D3D11ContextStateVS {
Com<D3D11VertexShader> shader;
D3D11GraphicsPipelineBindings bindings;
D3D11ConstantBufferBindings constantBuffers;
};
struct D3D11ContextStateHS {
Com<D3D11HullShader> shader;
D3D11GraphicsPipelineBindings bindings;
D3D11ConstantBufferBindings constantBuffers;
};
struct D3D11ContextStateDS {
Com<D3D11DomainShader> shader;
D3D11GraphicsPipelineBindings bindings;
D3D11ConstantBufferBindings constantBuffers;
};
struct D3D11ContextStateGS {
Com<D3D11GeometryShader> shader;
D3D11GraphicsPipelineBindings bindings;
D3D11ConstantBufferBindings constantBuffers;
};
struct D3D11ContextStatePS {
Com<D3D11PixelShader> shader;
D3D11GraphicsPipelineBindings bindings;
D3D11ConstantBufferBindings constantBuffers;
};
struct D3D11ContextStateCS {
Com<D3D11ComputeShader> shader;
D3D11ComputePipelineBindings bindings;
D3D11ConstantBufferBindings constantBuffers;
};

View File

@ -43,6 +43,7 @@ namespace dxvk {
DxbcValueType(DxbcScalarType::Float32, 4, elementCount));
uint32_t structType = m_module.defStructType(1, &arrayType);
m_module.decorateArrayStride(arrayType, 16);
m_module.memberDecorateOffset(structType, 0, 0);
m_module.decorateBlock(structType);
@ -50,8 +51,14 @@ namespace dxvk {
m_module.defPointerType(structType, spv::StorageClassUniform),
spv::StorageClassUniform);
m_module.setDebugName(varIndex, str::format("cb", bufferId).c_str());
m_module.decorateDescriptorSet(varIndex, 0);
m_module.decorateBinding(varIndex, 0);
m_constantBuffers.at(bufferId).varId = varIndex;
m_constantBuffers.at(bufferId).size = elementCount;
// TODO compute resource slot index
m_resourceSlots.push_back({ 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER });
}

View File

@ -156,7 +156,8 @@ namespace dxvk {
std::vector<DxbcPointer> m_rRegs;
std::array<DxbcConstantBuffer, 16> m_constantBuffers;
std::array<DxbcConstantBuffer, 16> m_constantBuffers;
std::vector<DxvkResourceSlot> m_resourceSlots;
uint32_t defScalarType(
DxbcScalarType type);

View File

@ -60,6 +60,7 @@ namespace dxvk {
m_module.decorateLocation(var.valueId, regId);
m_module.setDebugName(var.valueId,
str::format("v", regId).c_str());
m_entryPointInterfaces.push_back(var.valueId);
switch (im) {
case DxbcInterpolationMode::Undefined:
@ -168,7 +169,8 @@ namespace dxvk {
return new DxvkShader(
VK_SHADER_STAGE_FRAGMENT_BIT,
0, nullptr,
m_resourceSlots.size(),
m_resourceSlots.data(),
m_module.compile());
}

View File

@ -48,6 +48,7 @@ namespace dxvk {
m_module.decorateLocation(m_vRegs.at(regId).valueId, regId);
m_module.setDebugName(m_vRegs.at(regId).valueId,
str::format("v", regId).c_str());
m_entryPointInterfaces.push_back(m_vRegs.at(regId).valueId);
}
if (sv != DxbcSystemValue::None) {
@ -64,6 +65,7 @@ namespace dxvk {
m_module.decorateLocation(m_oRegs.at(regId).valueId, regId);
m_module.setDebugName(m_oRegs.at(regId).valueId,
str::format("o", regId).c_str());
m_entryPointInterfaces.push_back(m_oRegs.at(regId).valueId);
}
if (sv != DxbcSystemValue::None) {
@ -134,7 +136,8 @@ namespace dxvk {
return new DxvkShader(
VK_SHADER_STAGE_VERTEX_BIT,
0, nullptr,
m_resourceSlots.size(),
m_resourceSlots.data(),
m_module.compile());
}
@ -160,6 +163,7 @@ namespace dxvk {
this->regStore(this->ptrBuiltInPosition(), srcValue,
DxbcComponentMask(true, true, true, true));
} break;
default: ;
}
}
}

View File

@ -340,26 +340,29 @@ namespace dxvk {
VkDeviceSize offset,
VkDeviceSize size,
const void* data) {
this->renderPassEnd();
if (size == 0)
return;
if (size == VK_WHOLE_SIZE)
size = buffer->info().size;
if (size <= 65536) {
m_cmd->cmdUpdateBuffer(
buffer->handle(),
offset, size, data);
} else {
// TODO implement
Logger::err("DxvkContext::updateBuffer: Large updates not yet supported");
if (size != 0) {
if (size <= 65536) {
m_cmd->cmdUpdateBuffer(
buffer->handle(),
offset, size, data);
} else {
// TODO implement
Logger::err("DxvkContext::updateBuffer: Large updates not yet supported");
}
m_barriers.accessBuffer(
buffer, offset, size,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT,
buffer->info().stages,
buffer->info().access);
m_barriers.recordCommands(m_cmd);
}
m_barriers.accessBuffer(
buffer, offset, size,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT,
buffer->info().stages,
buffer->info().access);
m_barriers.recordCommands(m_cmd);
}

View File

@ -238,6 +238,16 @@ namespace dxvk {
}
void SpirvModule::decorateArrayStride(
uint32_t object,
uint32_t stride) {
m_annotations.putIns (spv::OpDecorate, 4);
m_annotations.putWord (object);
m_annotations.putWord (spv::DecorationArrayStride);
m_annotations.putInt32(stride);
}
void SpirvModule::decorateBinding(
uint32_t object,
uint32_t binding) {

View File

@ -88,6 +88,10 @@ namespace dxvk {
uint32_t object,
spv::Decoration decoration);
void decorateArrayStride(
uint32_t object,
uint32_t stride);
void decorateBinding(
uint32_t object,
uint32_t binding);

View File

@ -14,32 +14,17 @@ struct Extent2D {
struct Vertex {
float x, y, z, w;
float r, g, b, a;
};
const std::string g_vertexShaderCode =
"struct VsInput {\n"
" float4 position : IN_POSITION;\n"
" float4 color : IN_COLOR;\n"
"};\n"
"struct VsOutput {\n"
" float4 position : SV_POSITION;\n"
" float4 color : PS_COLOR;\n"
"};\n"
"VsOutput main(VsInput vsIn) {\n"
" VsOutput vsOut;\n"
" vsOut.position = vsIn.position;\n"
" vsOut.color = vsIn.color;\n"
" return vsOut;\n"
"float4 main(float4 vsIn : IN_POSITION) : SV_POSITION {\n"
" return vsIn;\n"
"}\n";
const std::string g_pixelShaderCode =
"struct PsInput {\n"
" float4 position : SV_POSITION;\n"
" float4 color : PS_COLOR;\n"
"};\n"
"float4 main(PsInput psIn) : SV_TARGET {\n"
" return psIn.color;\n"
"cbuffer c_buffer { float4 ccolor[2]; };\n"
"float4 main() : SV_TARGET {\n"
" return ccolor[0];\n"
"}\n";
class TriangleApp {
@ -97,9 +82,9 @@ public:
throw DxvkError("Failed to resize window");
std::array<Vertex, 3> vertexData = {{
{ -0.5f, -0.5f, 0.0f, 1.0f, 0.03f, 0.03f, 0.03f, 1.0f },
{ 0.0f, 0.5f, 0.0f, 1.0f, 0.03f, 0.03f, 0.03f, 1.0f },
{ 0.5f, -0.5f, 0.0f, 1.0f, 0.03f, 0.03f, 0.03f, 1.0f },
{ -0.5f, -0.5f, 0.0f, 1.0f },
{ 0.0f, 0.5f, 0.0f, 1.0f },
{ 0.5f, -0.5f, 0.0f, 1.0f },
}};
D3D11_BUFFER_DESC vertexDesc;
@ -115,6 +100,30 @@ public:
vertexDataInfo.SysMemPitch = 0;
vertexDataInfo.SysMemSlicePitch = 0;
if (FAILED(m_device->CreateBuffer(&vertexDesc, &vertexDataInfo, &m_vertexBuffer)))
throw DxvkError("Failed to create vertex buffer");
std::array<Vertex, 2> constantData = {{
{ 0.03f, 0.03f, 0.03f, 1.0f },
{ 1.00f, 1.00f, 1.00f, 1.0f },
}};
D3D11_BUFFER_DESC constantDesc;
constantDesc.ByteWidth = sizeof(Vertex) * constantData.size();
constantDesc.Usage = D3D11_USAGE_IMMUTABLE;
constantDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constantDesc.CPUAccessFlags = 0;
constantDesc.MiscFlags = 0;
constantDesc.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA constantDataInfo;
constantDataInfo.pSysMem = constantData.data();
constantDataInfo.SysMemPitch = 0;
constantDataInfo.SysMemSlicePitch = 0;
if (FAILED(m_device->CreateBuffer(&constantDesc, &constantDataInfo, &m_constantBuffer)))
throw DxvkError("Failed to create constant buffer");
Com<ID3DBlob> vertexShaderBlob;
Com<ID3DBlob> pixelShaderBlob;
@ -150,13 +159,8 @@ public:
nullptr, &m_pixelShader)))
throw DxvkError("Failed to create pixel shader");
if (FAILED(m_device->CreateBuffer(&vertexDesc, &vertexDataInfo, &m_vertexBuffer)))
throw DxvkError("Failed to create vertex buffer");
std::array<D3D11_INPUT_ELEMENT_DESC, 2> vertexFormatDesc = {{
std::array<D3D11_INPUT_ELEMENT_DESC, 1> vertexFormatDesc = {{
{ "IN_POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(Vertex, x), D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "IN_COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(Vertex, r), D3D11_INPUT_PER_VERTEX_DATA, 0 },
}};
if (FAILED(m_device->CreateInputLayout(
@ -193,6 +197,7 @@ public:
m_context->VSSetShader(m_vertexShader.ptr(), nullptr, 0);
m_context->PSSetShader(m_pixelShader.ptr(), nullptr, 0);
m_context->PSSetConstantBuffers(0, 1, &m_constantBuffer);
UINT vsStride = sizeof(Vertex);
UINT vsOffset = 0;
@ -247,6 +252,7 @@ private:
Com<ID3D11Texture2D> m_buffer;
Com<ID3D11RenderTargetView> m_bufferView;
Com<ID3D11Buffer> m_constantBuffer;
Com<ID3D11Buffer> m_vertexBuffer;
Com<ID3D11InputLayout> m_vertexFormat;