mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-02 19:24:12 +01:00
[dxvk] Initial work on instance data fetch rates
Adds a pipeline flag to indicate that instanced draw calls need to be emulated.
This commit is contained in:
parent
0154d0856d
commit
14d5054893
@ -731,17 +731,10 @@ namespace dxvk {
|
||||
// set by D3D11DeviceContext::IASetVertexBuffers.
|
||||
DxvkVertexBinding binding;
|
||||
binding.binding = pInputElementDescs[i].InputSlot;
|
||||
binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
|
||||
if (pInputElementDescs[i].InputSlotClass == D3D11_INPUT_PER_INSTANCE_DATA) {
|
||||
binding.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
|
||||
|
||||
if (pInputElementDescs[i].InstanceDataStepRate != 1) {
|
||||
Logger::warn(str::format(
|
||||
"D3D11Device: Unsupported instance data step rate: ",
|
||||
pInputElementDescs[i].InstanceDataStepRate));
|
||||
}
|
||||
}
|
||||
binding.fetchRate = pInputElementDescs[i].InstanceDataStepRate;
|
||||
binding.inputRate = pInputElementDescs[i].InputSlotClass == D3D11_INPUT_PER_INSTANCE_DATA
|
||||
? VK_VERTEX_INPUT_RATE_INSTANCE
|
||||
: VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
|
||||
// Check if the binding was already defined. If so, the
|
||||
// parameters must be identical (namely, the input rate).
|
||||
|
@ -4930,6 +4930,8 @@ namespace dxvk {
|
||||
m_module.setDebugName(typeId, "s_push_constant");
|
||||
m_module.setDebugMemberName(typeId, PerVertex_Position, "instance_id");
|
||||
|
||||
// There's only ever going to be one single push constant
|
||||
// block per shader, so we'll declare the variable here
|
||||
uint32_t ptrTypeId = m_module.defPointerType(
|
||||
typeId, spv::StorageClassPushConstant);
|
||||
|
||||
|
@ -333,6 +333,17 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void cmdPushConstants(
|
||||
VkPipelineLayout layout,
|
||||
VkShaderStageFlags stageFlags,
|
||||
uint32_t offset,
|
||||
uint32_t size,
|
||||
const void* pValues) {
|
||||
m_vkd->vkCmdPushConstants(m_buffer,
|
||||
layout, stageFlags, offset, size, pValues);
|
||||
}
|
||||
|
||||
|
||||
void cmdResolveImage(
|
||||
VkImage srcImage,
|
||||
VkImageLayout srcImageLayout,
|
||||
|
@ -136,6 +136,7 @@ namespace dxvk {
|
||||
*/
|
||||
struct DxvkVertexBinding {
|
||||
uint32_t binding;
|
||||
uint32_t fetchRate;
|
||||
VkVertexInputRate inputRate;
|
||||
};
|
||||
|
||||
|
@ -572,9 +572,16 @@ namespace dxvk {
|
||||
this->commitGraphicsState();
|
||||
|
||||
if (m_gpActivePipeline != VK_NULL_HANDLE) {
|
||||
m_cmd->cmdDraw(
|
||||
vertexCount, instanceCount,
|
||||
firstVertex, firstInstance);
|
||||
if (!m_flags.test(DxvkContextFlag::GpEmulateInstanceFetchRate)) {
|
||||
m_cmd->cmdDraw(
|
||||
vertexCount, instanceCount,
|
||||
firstVertex, firstInstance);
|
||||
} else {
|
||||
static bool errorShown = false;
|
||||
|
||||
if (!std::exchange(errorShown, true))
|
||||
Logger::warn("Dxvk: GpEmulateInstanceFetchRate not supported for direct draws");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -588,10 +595,17 @@ namespace dxvk {
|
||||
if (m_gpActivePipeline != VK_NULL_HANDLE) {
|
||||
auto physicalSlice = buffer.physicalSlice();
|
||||
|
||||
m_cmd->cmdDrawIndirect(
|
||||
physicalSlice.handle(),
|
||||
physicalSlice.offset(),
|
||||
count, stride);
|
||||
if (!m_flags.test(DxvkContextFlag::GpEmulateInstanceFetchRate)) {
|
||||
m_cmd->cmdDrawIndirect(
|
||||
physicalSlice.handle(),
|
||||
physicalSlice.offset(),
|
||||
count, stride);
|
||||
} else {
|
||||
static bool errorShown = false;
|
||||
|
||||
if (!std::exchange(errorShown, true))
|
||||
Logger::warn("Dxvk: GpEmulateInstanceFetchRate not supported for indirect draws");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1042,6 +1056,8 @@ namespace dxvk {
|
||||
m_flags.set(
|
||||
DxvkContextFlag::GpDirtyPipelineState,
|
||||
DxvkContextFlag::GpDirtyVertexBuffers);
|
||||
m_flags.clr(
|
||||
DxvkContextFlag::GpEmulateInstanceFetchRate);
|
||||
|
||||
for (uint32_t i = 0; i < attributeCount; i++) {
|
||||
m_state.gp.state.ilAttributes[i].location = attributes[i].location;
|
||||
@ -1056,6 +1072,10 @@ namespace dxvk {
|
||||
for (uint32_t i = 0; i < bindingCount; i++) {
|
||||
m_state.gp.state.ilBindings[i].binding = bindings[i].binding;
|
||||
m_state.gp.state.ilBindings[i].inputRate = bindings[i].inputRate;
|
||||
m_state.vi.vertexFetchRates[bindings[i].binding] = bindings[i].fetchRate;
|
||||
|
||||
if (bindings[i].inputRate == VK_VERTEX_INPUT_RATE_INSTANCE && bindings[i].fetchRate != 1)
|
||||
m_flags.set(DxvkContextFlag::GpEmulateInstanceFetchRate);
|
||||
}
|
||||
|
||||
for (uint32_t i = bindingCount; i < m_state.gp.state.ilBindingCount; i++)
|
||||
|
@ -558,12 +558,12 @@ namespace dxvk {
|
||||
|
||||
void updateShaderResources(
|
||||
VkPipelineBindPoint bindPoint,
|
||||
const Rc<DxvkPipelineLayout>& layout);
|
||||
const Rc<DxvkPipelineLayout>& layout);
|
||||
|
||||
void updateShaderDescriptors(
|
||||
VkPipelineBindPoint bindPoint,
|
||||
const DxvkBindingState& bindingState,
|
||||
const Rc<DxvkPipelineLayout>& layout);
|
||||
const Rc<DxvkPipelineLayout>& layout);
|
||||
|
||||
void updateViewports();
|
||||
void updateBlendConstants();
|
||||
|
@ -21,16 +21,17 @@ namespace dxvk {
|
||||
* be updated.
|
||||
*/
|
||||
enum class DxvkContextFlag : uint64_t {
|
||||
GpRenderPassBound, ///< Render pass is currently bound
|
||||
GpDirtyPipeline, ///< Graphics pipeline binding is out of date
|
||||
GpDirtyPipelineState, ///< Graphics pipeline needs to be recompiled
|
||||
GpDirtyResources, ///< Graphics pipeline resource bindings are out of date
|
||||
GpDirtyVertexBuffers, ///< Vertex buffer bindings are out of date
|
||||
GpDirtyIndexBuffer, ///< Index buffer binding are out of date
|
||||
GpRenderPassBound, ///< Render pass is currently bound
|
||||
GpDirtyPipeline, ///< Graphics pipeline binding is out of date
|
||||
GpDirtyPipelineState, ///< Graphics pipeline needs to be recompiled
|
||||
GpDirtyResources, ///< Graphics pipeline resource bindings are out of date
|
||||
GpDirtyVertexBuffers, ///< Vertex buffer bindings are out of date
|
||||
GpDirtyIndexBuffer, ///< Index buffer binding are out of date
|
||||
GpEmulateInstanceFetchRate, ///< The current input layout uses fetch rates != 1
|
||||
|
||||
CpDirtyPipeline, ///< Compute pipeline binding are out of date
|
||||
CpDirtyPipelineState, ///< Compute pipeline needs to be recompiled
|
||||
CpDirtyResources, ///< Compute pipeline resource bindings are out of date
|
||||
CpDirtyPipeline, ///< Compute pipeline binding are out of date
|
||||
CpDirtyPipelineState, ///< Compute pipeline needs to be recompiled
|
||||
CpDirtyResources, ///< Compute pipeline resource bindings are out of date
|
||||
};
|
||||
|
||||
using DxvkContextFlags = Flags<DxvkContextFlag>;
|
||||
@ -42,23 +43,25 @@ namespace dxvk {
|
||||
uint32_t bindingMask = 0;
|
||||
|
||||
std::array<DxvkBufferSlice,
|
||||
DxvkLimits::MaxNumVertexBindings> vertexBuffers;
|
||||
DxvkLimits::MaxNumVertexBindings> vertexBuffers = { };
|
||||
std::array<uint32_t,
|
||||
DxvkLimits::MaxNumVertexBindings> vertexStrides;
|
||||
DxvkLimits::MaxNumVertexBindings> vertexStrides = { };
|
||||
std::array<uint32_t,
|
||||
DxvkLimits::MaxNumVertexBindings> vertexFetchRates = { };
|
||||
};
|
||||
|
||||
|
||||
struct DxvkViewportState {
|
||||
std::array<VkViewport, DxvkLimits::MaxNumViewports> viewports;
|
||||
std::array<VkRect2D, DxvkLimits::MaxNumViewports> scissorRects;
|
||||
std::array<VkViewport, DxvkLimits::MaxNumViewports> viewports = { };
|
||||
std::array<VkRect2D, DxvkLimits::MaxNumViewports> scissorRects = { };
|
||||
};
|
||||
|
||||
|
||||
struct DxvkOutputMergerState {
|
||||
Rc<DxvkFramebuffer> framebuffer;
|
||||
|
||||
DxvkBlendConstants blendConstants;
|
||||
uint32_t stencilReference;
|
||||
DxvkBlendConstants blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
uint32_t stencilReference = 0;
|
||||
};
|
||||
|
||||
|
||||
@ -73,9 +76,9 @@ namespace dxvk {
|
||||
DxvkShaderStage tes;
|
||||
DxvkShaderStage gs;
|
||||
DxvkShaderStage fs;
|
||||
|
||||
|
||||
DxvkGraphicsPipelineStateInfo state;
|
||||
Rc<DxvkGraphicsPipeline> pipeline;
|
||||
Rc<DxvkGraphicsPipeline> pipeline;
|
||||
};
|
||||
|
||||
|
||||
|
@ -14,6 +14,7 @@ namespace dxvk {
|
||||
MaxNumActiveBindings = 128,
|
||||
MaxNumQueuedCommandBuffers = 8,
|
||||
MaxVertexBindingStride = 2048,
|
||||
MaxPushConstantSize = 128,
|
||||
};
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user