mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-18 13:54:16 +01:00
[d3d11] Implemented constant buffer binding
This commit is contained in:
parent
e872448ca3
commit
0610296248
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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 });
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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: ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user