Add support for VK_EXT_index_type_uint8

This commit is contained in:
baldurk
2019-08-12 17:50:39 +01:00
parent 2245957e38
commit 1fc9f36114
16 changed files with 367 additions and 25 deletions
+2
View File
@@ -782,6 +782,7 @@ DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceGroupProperties);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceHostQueryResetFeaturesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceIDProperties);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceImageFormatInfo2);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceIndexTypeUint8FeaturesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceMaintenance3Properties);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceMemoryBudgetPropertiesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceMemoryPriorityFeaturesEXT);
@@ -1020,6 +1021,7 @@ DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceGroupProperties);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceHostQueryResetFeaturesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceIDProperties);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceImageFormatInfo2);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceIndexTypeUint8FeaturesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceMaintenance3Properties);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceMemoryBudgetPropertiesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceMemoryPriorityFeaturesEXT);
+3
View File
@@ -705,6 +705,9 @@ static const VkExtensionProperties supportedExtensions[] = {
{
VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, VK_EXT_HOST_QUERY_RESET_SPEC_VERSION,
},
{
VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, VK_EXT_INDEX_TYPE_UINT8_SPEC_VERSION,
},
{
VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, VK_EXT_MEMORY_BUDGET_SPEC_VERSION,
},
+2 -1
View File
@@ -202,6 +202,8 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
VkPhysicalDeviceImageFormatInfo2); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT, \
VkPhysicalDeviceImageViewImageFormatInfoEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT, \
VkPhysicalDeviceIndexTypeUint8FeaturesEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, \
VkPhysicalDeviceMaintenance3Properties); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT, \
@@ -517,7 +519,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT: \
+9 -4
View File
@@ -332,6 +332,7 @@ void VulkanDebugManager::PatchLineStripIndexBuffer(const DrawcallDescription *dr
bytebuf indices;
uint8_t *idx8 = NULL;
uint16_t *idx16 = NULL;
uint32_t *idx32 = NULL;
@@ -341,16 +342,18 @@ void VulkanDebugManager::PatchLineStripIndexBuffer(const DrawcallDescription *dr
rs.ibuffer.offs + uint64_t(draw->indexOffset) * draw->indexByteWidth,
uint64_t(draw->numIndices) * draw->indexByteWidth, indices);
if(rs.ibuffer.bytewidth == 2)
idx16 = (uint16_t *)indices.data();
else
if(rs.ibuffer.bytewidth == 4)
idx32 = (uint32_t *)indices.data();
else if(rs.ibuffer.bytewidth == 1)
idx8 = (uint8_t *)indices.data();
else
idx16 = (uint16_t *)indices.data();
}
// we just patch up to 32-bit since we'll be adding more indices and we might overflow 16-bit.
std::vector<uint32_t> patchedIndices;
::PatchLineStripIndexBuffer(draw, NULL, idx16, idx32, patchedIndices);
::PatchLineStripIndexBuffer(draw, idx8, idx16, idx32, patchedIndices);
indexBuffer.Create(m_pDriver, m_Device, patchedIndices.size() * sizeof(uint32_t), 1,
GPUBuffer::eGPUBufferIBuffer);
@@ -2271,6 +2274,8 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeHint, Floa
VkIndexType idxtype = VK_INDEX_TYPE_UINT16;
if(fmt.indexByteStride == 4)
idxtype = VK_INDEX_TYPE_UINT32;
else if(fmt.indexByteStride == 1)
idxtype = VK_INDEX_TYPE_UINT8_EXT;
if(fmt.indexResourceId != ResourceId())
{
+43 -13
View File
@@ -1616,9 +1616,11 @@ void VulkanReplay::FetchVSOut(uint32_t eventId)
if(drawcall->flags & DrawFlags::Indexed)
{
bool index16 = (idxsize == 2);
const bool restart =
pipeCreateInfo.pInputAssemblyState->primitiveRestartEnable && IsStrip(drawcall->topology);
bytebuf idxdata;
std::vector<uint32_t> indices;
uint8_t *idx8 = NULL;
uint16_t *idx16 = NULL;
uint32_t *idx32 = NULL;
@@ -1666,12 +1668,15 @@ void VulkanReplay::FetchVSOut(uint32_t eventId)
// do ibuffer rebasing/remapping
idx16 = (uint16_t *)&idxdata[0];
idx32 = (uint32_t *)&idxdata[0];
if(idxsize == 4)
idx32 = (uint32_t *)&idxdata[0];
else if(idxsize == 1)
idx8 = (uint8_t *)&idxdata[0];
else
idx16 = (uint16_t *)&idxdata[0];
// only read as many indices as were available in the buffer
uint32_t numIndices =
RDCMIN(uint32_t(index16 ? idxdata.size() / 2 : idxdata.size() / 4), drawcall->numIndices);
uint32_t numIndices = RDCMIN(uint32_t(idxdata.size() / idxsize), drawcall->numIndices);
uint32_t idxclamp = 0;
if(drawcall->baseVertex < 0)
@@ -1680,7 +1685,13 @@ void VulkanReplay::FetchVSOut(uint32_t eventId)
// grab all unique vertex indices referenced
for(uint32_t i = 0; i < numIndices; i++)
{
uint32_t i32 = index16 ? uint32_t(idx16[i]) : idx32[i];
uint32_t i32 = 0;
if(idx32)
i32 = idx32[i];
else if(idx16)
i32 = uint32_t(idx16[i]);
else if(idx8)
i32 = uint32_t(idx8[i]);
// apply baseVertex but clamp to 0 (don't allow index to become negative)
if(i32 < idxclamp)
@@ -1798,10 +1809,16 @@ void VulkanReplay::FetchVSOut(uint32_t eventId)
// vertex buffer
for(uint32_t i = 0; i < numIndices; i++)
{
uint32_t i32 = index16 ? uint32_t(idx16[i]) : idx32[i];
uint32_t i32 = 0;
if(idx32)
i32 = idx32[i];
else if(idx16)
i32 = uint32_t(idx16[i]);
else if(idx8)
i32 = uint32_t(idx8[i]);
// preserve primitive restart indices
if(i32 == (index16 ? 0xffff : 0xffffffff))
if(restart && i32 == (0xffffffff >> ((4 - idxsize) * 8)))
continue;
// apply baseVertex but clamp to 0 (don't allow index to become negative)
@@ -1812,10 +1829,12 @@ void VulkanReplay::FetchVSOut(uint32_t eventId)
else if(drawcall->baseVertex > 0)
i32 += drawcall->baseVertex;
if(index16)
idx16[i] = uint16_t(indexRemap[i32]);
else
if(idx32)
idx32[i] = uint32_t(indexRemap[i32]);
else if(idx16)
idx16[i] = uint16_t(indexRemap[i32]);
else if(idx8)
idx8[i] = uint8_t(indexRemap[i32]);
}
bufInfo.size = RDCMAX((VkDeviceSize)64, (VkDeviceSize)idxdata.size());
@@ -2555,9 +2574,15 @@ void VulkanReplay::FetchVSOut(uint32_t eventId)
m_PostVS.Data[eventId].vsout.idxbuf = VK_NULL_HANDLE;
if(m_PostVS.Data[eventId].vsout.useIndices && state.ibuffer.buf != ResourceId())
{
VkIndexType type = VK_INDEX_TYPE_UINT16;
if(idxsize == 4)
type = VK_INDEX_TYPE_UINT32;
else if(idxsize == 1)
type = VK_INDEX_TYPE_UINT8_EXT;
m_PostVS.Data[eventId].vsout.idxbuf = rebasedIdxBuf;
m_PostVS.Data[eventId].vsout.idxbufmem = rebasedIdxBufMem;
m_PostVS.Data[eventId].vsout.idxFmt = idxsize == 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32;
m_PostVS.Data[eventId].vsout.idxFmt = type;
}
m_PostVS.Data[eventId].vsout.hasPosOut =
@@ -3251,7 +3276,12 @@ MeshFormat VulkanReplay::GetPostVSBuffers(uint32_t eventId, uint32_t instID, uin
if(s.useIndices && s.idxbuf != VK_NULL_HANDLE)
{
ret.indexResourceId = GetResID(s.idxbuf);
ret.indexByteStride = s.idxFmt == VK_INDEX_TYPE_UINT16 ? 2 : 4;
if(s.idxFmt == VK_INDEX_TYPE_UINT32)
ret.indexByteStride = 4;
else if(s.idxFmt == VK_INDEX_TYPE_UINT8_EXT)
ret.indexByteStride = 1;
else
ret.indexByteStride = 2;
}
else
{
@@ -498,6 +498,8 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const std::vector<MeshFormat> &s
VkIndexType idxtype = VK_INDEX_TYPE_UINT16;
if(fmt.indexByteStride == 4)
idxtype = VK_INDEX_TYPE_UINT32;
else if(fmt.indexByteStride == 1)
idxtype = VK_INDEX_TYPE_UINT8_EXT;
if(fmt.indexResourceId != ResourceId())
{
@@ -624,6 +626,8 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const std::vector<MeshFormat> &s
VkIndexType idxtype = VK_INDEX_TYPE_UINT16;
if(cfg.position.indexByteStride == 4)
idxtype = VK_INDEX_TYPE_UINT32;
else if(cfg.position.indexByteStride == 1)
idxtype = VK_INDEX_TYPE_UINT8_EXT;
if(cfg.position.indexResourceId != ResourceId())
{
@@ -671,6 +675,8 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const std::vector<MeshFormat> &s
VkIndexType idxtype = VK_INDEX_TYPE_UINT16;
if(cfg.position.indexByteStride == 4)
idxtype = VK_INDEX_TYPE_UINT32;
else if(cfg.position.indexByteStride == 1)
idxtype = VK_INDEX_TYPE_UINT8_EXT;
if(cfg.position.indexResourceId != ResourceId())
{
+21 -3
View File
@@ -538,6 +538,10 @@ SERIALISE_VK_HANDLES();
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT, \
VkPhysicalDeviceHostQueryResetFeaturesEXT) \
\
/* VK_EXT_index_type_uint8 */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT, \
VkPhysicalDeviceIndexTypeUint8FeaturesEXT) \
\
/* VK_EXT_memory_budget */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT, \
VkPhysicalDeviceMemoryBudgetPropertiesEXT) \
@@ -915,9 +919,6 @@ SERIALISE_VK_HANDLES();
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT) \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT) \
\
/* VK_EXT_index_type_uint8 */ \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT) \
\
/* VK_EXT_inline_uniform_block */ \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT) \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT) \
@@ -5885,6 +5886,22 @@ void Deserialise(const VkPhysicalDeviceMemoryBudgetPropertiesEXT &el)
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkPhysicalDeviceIndexTypeUint8FeaturesEXT &el)
{
RDCASSERT(ser.IsReading() ||
el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(indexTypeUint8);
}
template <>
void Deserialise(const VkPhysicalDeviceIndexTypeUint8FeaturesEXT &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkPhysicalDeviceMemoryPriorityFeaturesEXT &el)
{
@@ -6987,6 +7004,7 @@ INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceGroupProperties);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceHostQueryResetFeaturesEXT);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceIDProperties);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceImageFormatInfo2);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceIndexTypeUint8FeaturesEXT);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceMaintenance3Properties);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceMemoryBudgetPropertiesEXT);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceMemoryPriorityFeaturesEXT);
+9 -1
View File
@@ -282,9 +282,17 @@ void VulkanRenderState::BindPipeline(VkCommandBuffer cmd, PipelineBinding bindin
}
if(ibuffer.buf != ResourceId())
{
VkIndexType type = VK_INDEX_TYPE_UINT16;
if(ibuffer.bytewidth == 4)
type = VK_INDEX_TYPE_UINT32;
else if(ibuffer.bytewidth == 1)
type = VK_INDEX_TYPE_UINT8_EXT;
ObjDisp(cmd)->CmdBindIndexBuffer(
Unwrap(cmd), Unwrap(GetResourceManager()->GetCurrentHandle<VkBuffer>(ibuffer.buf)),
ibuffer.offs, ibuffer.bytewidth == 4 ? VK_INDEX_TYPE_UINT32 : VK_INDEX_TYPE_UINT16);
ibuffer.offs, type);
}
for(size_t i = 0; i < vbuffers.size(); i++)
{
@@ -2248,15 +2248,25 @@ bool WrappedVulkan::Serialise_vkCmdBindIndexBuffer(SerialiserType &ser,
{
m_RenderState.ibuffer.buf = GetResID(buffer);
m_RenderState.ibuffer.offs = offset;
m_RenderState.ibuffer.bytewidth = indexType == VK_INDEX_TYPE_UINT32 ? 4 : 2;
if(indexType == VK_INDEX_TYPE_UINT32)
m_RenderState.ibuffer.bytewidth = 4;
else if(indexType == VK_INDEX_TYPE_UINT8_EXT)
m_RenderState.ibuffer.bytewidth = 1;
else
m_RenderState.ibuffer.bytewidth = 2;
}
}
}
else
{
// track while reading, as we need to bind current topology & index byte width in AddDrawcall
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.idxWidth =
(indexType == VK_INDEX_TYPE_UINT32 ? 4 : 2);
if(indexType == VK_INDEX_TYPE_UINT32)
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.idxWidth = 4;
else if(indexType == VK_INDEX_TYPE_UINT8_EXT)
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.idxWidth = 1;
else
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.idxWidth = 2;
// track while reading, as we need to track resource usage
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.ibuffer = GetResID(buffer);
@@ -2105,6 +2105,13 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
CHECK_PHYS_EXT_FEATURE(texelBufferAlignment);
}
END_PHYS_EXT_CHECK();
BEGIN_PHYS_EXT_CHECK(VkPhysicalDeviceIndexTypeUint8FeaturesEXT,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT);
{
CHECK_PHYS_EXT_FEATURE(indexTypeUint8);
}
END_PHYS_EXT_CHECK();
}
if(availFeatures.depthClamp)
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

+1
View File
@@ -14,6 +14,7 @@ set(VULKAN_SRC
vk/vk_draw_zoo.cpp
vk/vk_image_layouts.cpp
vk/vk_indirect.cpp
vk/vk_int8_ibuffer.cpp
vk/vk_multi_thread_windows.cpp
vk/vk_overlay_test.cpp
vk/vk_resource_lifetimes.cpp
+1
View File
@@ -209,6 +209,7 @@
<ClCompile Include="main.cpp" />
<ClCompile Include="test_common.cpp" />
<ClCompile Include="vk\vk_image_layouts.cpp" />
<ClCompile Include="vk\vk_int8_ibuffer.cpp" />
<ClCompile Include="vk\vk_multi_thread_windows.cpp" />
<ClCompile Include="vk\vk_vertex_attr_zoo.cpp" />
<ClCompile Include="vk\vk_buffer_address.cpp" />
+3
View File
@@ -309,6 +309,9 @@
<ClCompile Include="d3d11\d3d11_stream_out.cpp">
<Filter>D3D11\demos</Filter>
</ClCompile>
<ClCompile Include="vk\vk_int8_ibuffer.cpp">
<Filter>Vulkan\demos</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="D3D11">
+195
View File
@@ -0,0 +1,195 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2018-2019 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "vk_test.h"
TEST(VK_Int8_IBuffer, VulkanGraphicsTest)
{
static constexpr const char *Description = "Draws a triangle strip with 8-bit width indices";
std::string common = R"EOSHADER(
#version 420 core
struct v2f
{
vec4 pos;
vec4 col;
vec4 uv;
};
)EOSHADER";
const std::string vertex = R"EOSHADER(
layout(location = 0) in vec3 Position;
layout(location = 1) in vec4 Color;
layout(location = 2) in vec2 UV;
layout(location = 0) out v2f vertOut;
void main()
{
vertOut.pos = vec4(Position.xyz*vec3(1,-1,1), 1);
gl_Position = vertOut.pos;
vertOut.col = Color;
vertOut.uv = vec4(UV.xy, 0, 1);
}
)EOSHADER";
const std::string pixel = R"EOSHADER(
layout(location = 0) in v2f vertIn;
layout(location = 0, index = 0) out vec4 Color;
void main()
{
Color = vertIn.col;
}
)EOSHADER";
void Prepare(int argc, char **argv)
{
devExts.push_back(VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME);
VulkanGraphicsTest::Prepare(argc, argv);
}
int main()
{
// initialise, create window, create context, etc
if(!Init())
return 3;
VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo());
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
pipeCreateInfo.layout = layout;
pipeCreateInfo.renderPass = mainWindow->rp;
pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
vkh::vertexAttr(0, 0, DefaultA2V, pos), vkh::vertexAttr(1, 0, DefaultA2V, col),
vkh::vertexAttr(2, 0, DefaultA2V, uv),
};
pipeCreateInfo.stages = {
CompileShaderModule(common + vertex, ShaderLang::glsl, ShaderStage::vert, "main"),
CompileShaderModule(common + pixel, ShaderLang::glsl, ShaderStage::frag, "main"),
};
pipeCreateInfo.inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
pipeCreateInfo.inputAssemblyState.primitiveRestartEnable = VK_TRUE;
VkPipeline pipe = createGraphicsPipeline(pipeCreateInfo);
DefaultA2V strip[] = {
{Vec3f(-0.8f, 0.2f, 0.0f), Vec4f(1.0f, 0.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(-0.8f, 0.7f, 0.0f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(-0.4f, 0.2f, 0.0f), Vec4f(0.0f, 0.0f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(-0.4f, 0.7f, 0.0f), Vec4f(1.0f, 0.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(0.0f, 0.2f, 0.0f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(0.0f, 0.7f, 0.0f), Vec4f(0.0f, 0.0f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(0.4f, 0.2f, 0.0f), Vec4f(1.0f, 0.0f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(0.4f, 0.7f, 0.0f), Vec4f(1.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(-0.8f, -0.7f, 0.0f), Vec4f(1.0f, 0.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(-0.8f, -0.2f, 0.0f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(-0.4f, -0.7f, 0.0f), Vec4f(0.0f, 0.0f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(-0.4f, -0.2f, 0.0f), Vec4f(1.0f, 0.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(0.0f, -0.7f, 0.0f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(0.0f, -0.2f, 0.0f), Vec4f(0.0f, 0.0f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(0.4f, -0.7f, 0.0f), Vec4f(1.0f, 0.0f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(0.4f, -0.2f, 0.0f), Vec4f(1.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
};
AllocatedBuffer vb(allocator,
vkh::BufferCreateInfo(sizeof(strip), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
vb.upload(strip);
uint8_t idx[] = {
// strip 0
0, 1, 2, 3, 4, 5, 6, 7,
// restart
0xff,
// strip 1
8, 9, 10, 11, 12, 13, 14, 15,
};
AllocatedBuffer ib(allocator,
vkh::BufferCreateInfo(sizeof(idx), VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
ib.upload(idx);
while(Running())
{
VkCommandBuffer cmd = GetCommandBuffer();
vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());
VkImage swapimg =
StartUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
vkCmdClearColorImage(cmd, swapimg, VK_IMAGE_LAYOUT_GENERAL,
vkh::ClearColorValue(0.4f, 0.5f, 0.6f, 1.0f), 1,
vkh::ImageSubresourceRange());
vkCmdBeginRenderPass(
cmd, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(), mainWindow->scissor),
VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
vkCmdBindIndexBuffer(cmd, ib.buffer, 0, VK_INDEX_TYPE_UINT8_EXT);
vkCmdDrawIndexed(cmd, 17, 1, 0, 0, 0);
vkCmdEndRenderPass(cmd);
FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
vkEndCommandBuffer(cmd);
Submit(0, 1, {cmd});
Present();
}
return 0;
}
};
REGISTER_TEST();
+52
View File
@@ -0,0 +1,52 @@
import rdtest
import renderdoc as rd
class VK_Int8_IBuffer(rdtest.TestCase):
demos_test_name = 'VK_Int8_IBuffer'
def check_capture(self):
self.check_final_backbuffer()
draw = self.find_draw("Draw")
self.check(draw is not None)
self.controller.SetFrameEvent(draw.eventId, False)
pipe: rd.PipeState = self.controller.GetPipelineState()
postvs_data = self.get_postvs(rd.MeshDataStage.VSOut, 0, draw.numIndices)
# Calculate the strip restart index for this index width
striprestart_index = pipe.GetStripRestartIndex() & ((1 << (draw.indexByteWidth*8)) - 1)
# We don't check all of the output, we check a few key vertices to ensure they match up
postvs_ref = {
0: {
'vtx': 0,
'idx': 0,
'gl_PerVertex.gl_Position': [-0.8, -0.2, 0.0, 1.0],
'vertOut.col': [1.0, 0.0, 0.0, 1.0],
'vertOut.uv': [0.0, 0.0, 0.0, 1.0],
},
4: {
'vtx': 4,
'idx': 4,
'gl_PerVertex.gl_Position': [0.0, -0.2, 0.0, 1.0],
'vertOut.col': [0.0, 1.0, 0.0, 1.0],
'vertOut.uv': [0.0, 0.0, 0.0, 1.0],
},
8: {
'idx': striprestart_index
},
9: {
'vtx': 9,
'idx': 8,
'gl_PerVertex.gl_Position': [-0.8, 0.7, 0.0, 1.0],
'vertOut.col': [1.0, 0.0, 0.0, 1.0],
'vertOut.uv': [0.0, 0.0, 0.0, 1.0],
},
}
self.check_mesh_data(postvs_ref, postvs_data)