mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-06 06:33:30 +00:00
Wire: Add support from optional struct/integer const*
This will allow implementing the following part of the WebGPU IDL using a nullable pointer instead of an extra hasDepthStencilState boolean: partial interface GPURenderPipelineDescriptor { GPUDepthStencilStateDescriptor? depthStencilState; }; BUG=dawn:102 Change-Id: Iae709831ad857fcef073f18753ab39567a8797da Reviewed-on: https://dawn-review.googlesource.com/c/4500 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org> Reviewed-by: Yunchao He <yunchao.he@intel.com>
This commit is contained in:
parent
bb5696bcd3
commit
f872e6924c
@ -863,7 +863,7 @@
|
|||||||
{"name": "primitive topology", "type": "primitive topology"},
|
{"name": "primitive topology", "type": "primitive topology"},
|
||||||
{"name": "attachments state", "type": "attachments state descriptor", "annotation": "const*"},
|
{"name": "attachments state", "type": "attachments state descriptor", "annotation": "const*"},
|
||||||
{"name": "sample count", "type": "uint32_t"},
|
{"name": "sample count", "type": "uint32_t"},
|
||||||
{"name": "depth stencil state", "type": "depth stencil state descriptor", "annotation": "const*"},
|
{"name": "depth stencil state", "type": "depth stencil state descriptor", "annotation": "const*", "optional": true},
|
||||||
{"name": "num blend states", "type": "uint32_t"},
|
{"name": "num blend states", "type": "uint32_t"},
|
||||||
{"name": "blend states", "type": "blend state descriptor", "annotation": "const*", "length": "num blend states"}
|
{"name": "blend states", "type": "blend state descriptor", "annotation": "const*", "length": "num blend states"}
|
||||||
]
|
]
|
||||||
|
@ -105,6 +105,10 @@
|
|||||||
{% for member in members if member.length == "strlen" %}
|
{% for member in members if member.length == "strlen" %}
|
||||||
size_t {{as_varName(member.name)}}Strlen;
|
size_t {{as_varName(member.name)}}Strlen;
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
{% for member in members if member.annotation != "value" and member.type.category != "object" %}
|
||||||
|
bool has_{{as_varName(member.name)}};
|
||||||
|
{% endfor %}
|
||||||
};
|
};
|
||||||
|
|
||||||
//* Returns the required transfer size for `record` in addition to the transfer structure.
|
//* Returns the required transfer size for `record` in addition to the transfer structure.
|
||||||
@ -120,6 +124,9 @@
|
|||||||
|
|
||||||
//* Gather how much space will be needed for pointer members.
|
//* Gather how much space will be needed for pointer members.
|
||||||
{% for member in members if member.annotation != "value" and member.length != "strlen" %}
|
{% for member in members if member.annotation != "value" and member.length != "strlen" %}
|
||||||
|
{% if member.type.category != "object" and member.optional %}
|
||||||
|
if (record.{{as_varName(member.name)}} != nullptr)
|
||||||
|
{% endif %}
|
||||||
{
|
{
|
||||||
size_t memberLength = {{member_length(member, "record.")}};
|
size_t memberLength = {{member_length(member, "record.")}};
|
||||||
result += memberLength * {{member_transfer_sizeof(member)}};
|
result += memberLength * {{member_transfer_sizeof(member)}};
|
||||||
@ -176,6 +183,12 @@
|
|||||||
//* Allocate space and write the non-value arguments in it.
|
//* Allocate space and write the non-value arguments in it.
|
||||||
{% for member in members if member.annotation != "value" and member.length != "strlen" %}
|
{% for member in members if member.annotation != "value" and member.length != "strlen" %}
|
||||||
{% set memberName = as_varName(member.name) %}
|
{% set memberName = as_varName(member.name) %}
|
||||||
|
|
||||||
|
{% if member.type.category != "object" and member.optional %}
|
||||||
|
bool has_{{memberName}} = record.{{memberName}} != nullptr;
|
||||||
|
transfer->has_{{memberName}} = has_{{memberName}};
|
||||||
|
if (has_{{memberName}})
|
||||||
|
{% endif %}
|
||||||
{
|
{
|
||||||
size_t memberLength = {{member_length(member, "record.")}};
|
size_t memberLength = {{member_length(member, "record.")}};
|
||||||
auto memberBuffer = reinterpret_cast<{{member_transfer_type(member)}}*>(*buffer);
|
auto memberBuffer = reinterpret_cast<{{member_transfer_type(member)}}*>(*buffer);
|
||||||
@ -277,6 +290,12 @@
|
|||||||
//* Get extra buffer data, and copy pointed to values in extra allocated space.
|
//* Get extra buffer data, and copy pointed to values in extra allocated space.
|
||||||
{% for member in members if member.annotation != "value" and member.length != "strlen" %}
|
{% for member in members if member.annotation != "value" and member.length != "strlen" %}
|
||||||
{% set memberName = as_varName(member.name) %}
|
{% set memberName = as_varName(member.name) %}
|
||||||
|
|
||||||
|
{% if member.type.category != "object" and member.optional %}
|
||||||
|
bool has_{{memberName}} = transfer->has_{{memberName}};
|
||||||
|
record->{{memberName}} = nullptr;
|
||||||
|
if (has_{{memberName}})
|
||||||
|
{% endif %}
|
||||||
{
|
{
|
||||||
size_t memberLength = {{member_length(member, "record->")}};
|
size_t memberLength = {{member_length(member, "record->")}};
|
||||||
auto memberBuffer = reinterpret_cast<const {{member_transfer_type(member)}}*>(buffer);
|
auto memberBuffer = reinterpret_cast<const {{member_transfer_type(member)}}*>(buffer);
|
||||||
|
@ -439,6 +439,141 @@ TEST_F(WireTests, CStringArgument) {
|
|||||||
FlushClient();
|
FlushClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that the wire is able to send optional pointers to structures
|
||||||
|
TEST_F(WireTests, OptionalStructPointer) {
|
||||||
|
// Create shader module
|
||||||
|
dawnShaderModuleDescriptor vertexDescriptor;
|
||||||
|
vertexDescriptor.nextInChain = nullptr;
|
||||||
|
vertexDescriptor.codeSize = 0;
|
||||||
|
dawnShaderModule vsModule = dawnDeviceCreateShaderModule(device, &vertexDescriptor);
|
||||||
|
dawnShaderModule apiVsModule = api.GetNewShaderModule();
|
||||||
|
EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _))
|
||||||
|
.WillOnce(Return(apiVsModule));
|
||||||
|
|
||||||
|
// Create the blend state descriptor
|
||||||
|
dawnBlendDescriptor blendDescriptor;
|
||||||
|
blendDescriptor.operation = DAWN_BLEND_OPERATION_ADD;
|
||||||
|
blendDescriptor.srcFactor = DAWN_BLEND_FACTOR_ONE;
|
||||||
|
blendDescriptor.dstFactor = DAWN_BLEND_FACTOR_ONE;
|
||||||
|
dawnBlendStateDescriptor blendStateDescriptor;
|
||||||
|
blendStateDescriptor.nextInChain = nullptr;
|
||||||
|
blendStateDescriptor.alphaBlend = blendDescriptor;
|
||||||
|
blendStateDescriptor.colorBlend = blendDescriptor;
|
||||||
|
blendStateDescriptor.colorWriteMask = DAWN_COLOR_WRITE_MASK_ALL;
|
||||||
|
|
||||||
|
// Create the input state
|
||||||
|
dawnInputStateBuilder inputStateBuilder = dawnDeviceCreateInputStateBuilder(device);
|
||||||
|
dawnInputStateBuilder apiInputStateBuilder = api.GetNewInputStateBuilder();
|
||||||
|
EXPECT_CALL(api, DeviceCreateInputStateBuilder(apiDevice))
|
||||||
|
.WillOnce(Return(apiInputStateBuilder));
|
||||||
|
|
||||||
|
dawnInputState inputState = dawnInputStateBuilderGetResult(inputStateBuilder);
|
||||||
|
dawnInputState apiInputState = api.GetNewInputState();
|
||||||
|
EXPECT_CALL(api, InputStateBuilderGetResult(apiInputStateBuilder))
|
||||||
|
.WillOnce(Return(apiInputState));
|
||||||
|
|
||||||
|
// Create the depth-stencil state
|
||||||
|
dawnStencilStateFaceDescriptor stencilFace;
|
||||||
|
stencilFace.compare = DAWN_COMPARE_FUNCTION_ALWAYS;
|
||||||
|
stencilFace.failOp = DAWN_STENCIL_OPERATION_KEEP;
|
||||||
|
stencilFace.depthFailOp = DAWN_STENCIL_OPERATION_KEEP;
|
||||||
|
stencilFace.passOp = DAWN_STENCIL_OPERATION_KEEP;
|
||||||
|
|
||||||
|
dawnDepthStencilStateDescriptor depthStencilState;
|
||||||
|
depthStencilState.nextInChain = nullptr;
|
||||||
|
depthStencilState.depthWriteEnabled = false;
|
||||||
|
depthStencilState.depthCompare = DAWN_COMPARE_FUNCTION_ALWAYS;
|
||||||
|
depthStencilState.stencilBack = stencilFace;
|
||||||
|
depthStencilState.stencilFront = stencilFace;
|
||||||
|
depthStencilState.stencilReadMask = 0xff;
|
||||||
|
depthStencilState.stencilWriteMask = 0xff;
|
||||||
|
|
||||||
|
// Create the pipeline layout
|
||||||
|
dawnPipelineLayoutDescriptor layoutDescriptor;
|
||||||
|
layoutDescriptor.nextInChain = nullptr;
|
||||||
|
layoutDescriptor.numBindGroupLayouts = 0;
|
||||||
|
layoutDescriptor.bindGroupLayouts = nullptr;
|
||||||
|
dawnPipelineLayout layout = dawnDeviceCreatePipelineLayout(device, &layoutDescriptor);
|
||||||
|
dawnPipelineLayout apiLayout = api.GetNewPipelineLayout();
|
||||||
|
EXPECT_CALL(api, DeviceCreatePipelineLayout(apiDevice, _))
|
||||||
|
.WillOnce(Return(apiLayout));
|
||||||
|
|
||||||
|
// Create pipeline
|
||||||
|
dawnRenderPipelineDescriptor pipelineDescriptor;
|
||||||
|
pipelineDescriptor.nextInChain = nullptr;
|
||||||
|
|
||||||
|
dawnPipelineStageDescriptor vertexStage;
|
||||||
|
vertexStage.nextInChain = nullptr;
|
||||||
|
vertexStage.module = vsModule;
|
||||||
|
vertexStage.entryPoint = "main";
|
||||||
|
pipelineDescriptor.vertexStage = &vertexStage;
|
||||||
|
|
||||||
|
dawnPipelineStageDescriptor fragmentStage;
|
||||||
|
fragmentStage.nextInChain = nullptr;
|
||||||
|
fragmentStage.module = vsModule;
|
||||||
|
fragmentStage.entryPoint = "main";
|
||||||
|
pipelineDescriptor.fragmentStage = &fragmentStage;
|
||||||
|
|
||||||
|
dawnAttachmentsStateDescriptor attachmentsState;
|
||||||
|
attachmentsState.nextInChain = nullptr;
|
||||||
|
attachmentsState.numColorAttachments = 1;
|
||||||
|
dawnAttachmentDescriptor colorAttachment = {nullptr, DAWN_TEXTURE_FORMAT_R8_G8_B8_A8_UNORM};
|
||||||
|
dawnAttachmentDescriptor* colorAttachmentPtr[] = {&colorAttachment};
|
||||||
|
attachmentsState.colorAttachments = colorAttachmentPtr;
|
||||||
|
attachmentsState.hasDepthStencilAttachment = false;
|
||||||
|
// Even with hasDepthStencilAttachment = false, depthStencilAttachment must point to valid
|
||||||
|
// data because we don't have optional substructures yet.
|
||||||
|
attachmentsState.depthStencilAttachment = &colorAttachment;
|
||||||
|
pipelineDescriptor.attachmentsState = &attachmentsState;
|
||||||
|
|
||||||
|
pipelineDescriptor.numBlendStates = 1;
|
||||||
|
pipelineDescriptor.blendStates = &blendStateDescriptor;
|
||||||
|
|
||||||
|
pipelineDescriptor.sampleCount = 1;
|
||||||
|
pipelineDescriptor.layout = layout;
|
||||||
|
pipelineDescriptor.inputState = inputState;
|
||||||
|
pipelineDescriptor.indexFormat = DAWN_INDEX_FORMAT_UINT32;
|
||||||
|
pipelineDescriptor.primitiveTopology = DAWN_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||||
|
|
||||||
|
// First case: depthStencilState is not null.
|
||||||
|
pipelineDescriptor.depthStencilState = &depthStencilState;
|
||||||
|
dawnDeviceCreateRenderPipeline(device, &pipelineDescriptor);
|
||||||
|
EXPECT_CALL(api, DeviceCreateRenderPipeline(apiDevice, MatchesLambda([](const dawnRenderPipelineDescriptor* desc) -> bool {
|
||||||
|
return desc->depthStencilState != nullptr &&
|
||||||
|
desc->depthStencilState->nextInChain == nullptr &&
|
||||||
|
desc->depthStencilState->depthWriteEnabled == false &&
|
||||||
|
desc->depthStencilState->depthCompare == DAWN_COMPARE_FUNCTION_ALWAYS &&
|
||||||
|
desc->depthStencilState->stencilBack.compare == DAWN_COMPARE_FUNCTION_ALWAYS &&
|
||||||
|
desc->depthStencilState->stencilBack.failOp == DAWN_STENCIL_OPERATION_KEEP &&
|
||||||
|
desc->depthStencilState->stencilBack.depthFailOp == DAWN_STENCIL_OPERATION_KEEP &&
|
||||||
|
desc->depthStencilState->stencilBack.passOp == DAWN_STENCIL_OPERATION_KEEP &&
|
||||||
|
desc->depthStencilState->stencilFront.compare == DAWN_COMPARE_FUNCTION_ALWAYS &&
|
||||||
|
desc->depthStencilState->stencilFront.failOp == DAWN_STENCIL_OPERATION_KEEP &&
|
||||||
|
desc->depthStencilState->stencilFront.depthFailOp == DAWN_STENCIL_OPERATION_KEEP &&
|
||||||
|
desc->depthStencilState->stencilFront.passOp == DAWN_STENCIL_OPERATION_KEEP &&
|
||||||
|
desc->depthStencilState->stencilReadMask == 0xff &&
|
||||||
|
desc->depthStencilState->stencilWriteMask == 0xff;
|
||||||
|
})))
|
||||||
|
.WillOnce(Return(nullptr));
|
||||||
|
|
||||||
|
FlushClient();
|
||||||
|
|
||||||
|
// Second case: depthStencilState is null.
|
||||||
|
pipelineDescriptor.depthStencilState = nullptr;
|
||||||
|
dawnDeviceCreateRenderPipeline(device, &pipelineDescriptor);
|
||||||
|
EXPECT_CALL(api, DeviceCreateRenderPipeline(apiDevice, MatchesLambda([](const dawnRenderPipelineDescriptor* desc) -> bool {
|
||||||
|
return desc->depthStencilState == nullptr;
|
||||||
|
})))
|
||||||
|
.WillOnce(Return(nullptr));
|
||||||
|
|
||||||
|
EXPECT_CALL(api, ShaderModuleRelease(apiVsModule));
|
||||||
|
EXPECT_CALL(api, InputStateBuilderRelease(apiInputStateBuilder));
|
||||||
|
EXPECT_CALL(api, InputStateRelease(apiInputState));
|
||||||
|
EXPECT_CALL(api, PipelineLayoutRelease(apiLayout));
|
||||||
|
|
||||||
|
FlushClient();
|
||||||
|
}
|
||||||
|
|
||||||
// Test that the wire is able to send objects as value arguments
|
// Test that the wire is able to send objects as value arguments
|
||||||
TEST_F(WireTests, ObjectAsValueArgument) {
|
TEST_F(WireTests, ObjectAsValueArgument) {
|
||||||
// Create a RenderPassDescriptor
|
// Create a RenderPassDescriptor
|
||||||
|
Loading…
x
Reference in New Issue
Block a user