Validate SetPushConstants is done inside subpass and compute passes
This commit is contained in:
parent
be985c1aab
commit
c8377da79b
|
@ -380,7 +380,7 @@
|
||||||
"TODO Vulkan has an additional stage mask"
|
"TODO Vulkan has an additional stage mask"
|
||||||
],
|
],
|
||||||
"args": [
|
"args": [
|
||||||
{"name": "stage", "type": "shader stage bit"},
|
{"name": "stages", "type": "shader stage bit"},
|
||||||
{"name": "offset", "type": "uint32_t"},
|
{"name": "offset", "type": "uint32_t"},
|
||||||
{"name": "count", "type": "uint32_t"},
|
{"name": "count", "type": "uint32_t"},
|
||||||
{"name": "data", "type": "uint32_t", "annotation": "const*", "length": "count"}
|
{"name": "data", "type": "uint32_t", "annotation": "const*", "length": "count"}
|
||||||
|
|
|
@ -552,8 +552,9 @@ namespace backend {
|
||||||
{
|
{
|
||||||
SetPushConstantsCmd* cmd = iterator.NextCommand<SetPushConstantsCmd>();
|
SetPushConstantsCmd* cmd = iterator.NextCommand<SetPushConstantsCmd>();
|
||||||
iterator.NextData<uint32_t>(cmd->count);
|
iterator.NextData<uint32_t>(cmd->count);
|
||||||
if (cmd->count + cmd->offset > kMaxPushConstants) {
|
// Validation of count and offset has already been done when the command was recorded
|
||||||
HandleError("Setting pushconstants past the limit");
|
// because it impacts the size of an allocation in the CommandAllocator.
|
||||||
|
if (!state->ValidateSetPushConstants(cmd->stages)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -755,7 +756,8 @@ namespace backend {
|
||||||
cmd->pipeline = pipeline;
|
cmd->pipeline = pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBufferBuilder::SetPushConstants(nxt::ShaderStageBit stage, uint32_t offset, uint32_t count, const void* data) {
|
void CommandBufferBuilder::SetPushConstants(nxt::ShaderStageBit stages, uint32_t offset, uint32_t count, const void* data) {
|
||||||
|
// TODO(cwallez@chromium.org): check for overflows
|
||||||
if (offset + count > kMaxPushConstants) {
|
if (offset + count > kMaxPushConstants) {
|
||||||
HandleError("Setting too many push constants");
|
HandleError("Setting too many push constants");
|
||||||
return;
|
return;
|
||||||
|
@ -763,7 +765,7 @@ namespace backend {
|
||||||
|
|
||||||
SetPushConstantsCmd* cmd = allocator.Allocate<SetPushConstantsCmd>(Command::SetPushConstants);
|
SetPushConstantsCmd* cmd = allocator.Allocate<SetPushConstantsCmd>(Command::SetPushConstants);
|
||||||
new(cmd) SetPushConstantsCmd;
|
new(cmd) SetPushConstantsCmd;
|
||||||
cmd->stage = stage;
|
cmd->stages = stages;
|
||||||
cmd->offset = offset;
|
cmd->offset = offset;
|
||||||
cmd->count = count;
|
cmd->count = count;
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ namespace backend {
|
||||||
void EndComputePass();
|
void EndComputePass();
|
||||||
void EndRenderPass();
|
void EndRenderPass();
|
||||||
void EndRenderSubpass();
|
void EndRenderSubpass();
|
||||||
void SetPushConstants(nxt::ShaderStageBit stage, uint32_t offset, uint32_t count, const void* data);
|
void SetPushConstants(nxt::ShaderStageBit stages, uint32_t offset, uint32_t count, const void* data);
|
||||||
void SetComputePipeline(ComputePipelineBase* pipeline);
|
void SetComputePipeline(ComputePipelineBase* pipeline);
|
||||||
void SetRenderPipeline(RenderPipelineBase* pipeline);
|
void SetRenderPipeline(RenderPipelineBase* pipeline);
|
||||||
void SetStencilReference(uint32_t reference);
|
void SetStencilReference(uint32_t reference);
|
||||||
|
|
|
@ -127,6 +127,24 @@ namespace backend {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CommandBufferStateTracker::ValidateSetPushConstants(nxt::ShaderStageBit stages) {
|
||||||
|
if (aspects[VALIDATION_ASPECT_COMPUTE_PASS]) {
|
||||||
|
if (stages & ~nxt::ShaderStageBit::Compute) {
|
||||||
|
builder->HandleError("SetPushConstants stage must be compute or 0 in compute passes");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (aspects[VALIDATION_ASPECT_RENDER_SUBPASS]) {
|
||||||
|
if (stages & ~(nxt::ShaderStageBit::Vertex | nxt::ShaderStageBit::Fragment)) {
|
||||||
|
builder->HandleError("SetPushConstants stage must be a subset if (vertex|fragment) in subpasses");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
builder->HandleError("PushConstants must be set in either compute passes or subpasses");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool CommandBufferStateTracker::BeginComputePass() {
|
bool CommandBufferStateTracker::BeginComputePass() {
|
||||||
if (currentRenderPass != nullptr) {
|
if (currentRenderPass != nullptr) {
|
||||||
builder->HandleError("Cannot begin a compute pass while a render pass is active");
|
builder->HandleError("Cannot begin a compute pass while a render pass is active");
|
||||||
|
|
|
@ -37,6 +37,7 @@ namespace backend {
|
||||||
bool ValidateCanDrawArrays();
|
bool ValidateCanDrawArrays();
|
||||||
bool ValidateCanDrawElements();
|
bool ValidateCanDrawElements();
|
||||||
bool ValidateEndCommandBuffer() const;
|
bool ValidateEndCommandBuffer() const;
|
||||||
|
bool ValidateSetPushConstants(nxt::ShaderStageBit stages);
|
||||||
|
|
||||||
// State-modifying methods
|
// State-modifying methods
|
||||||
bool BeginComputePass();
|
bool BeginComputePass();
|
||||||
|
|
|
@ -130,7 +130,7 @@ namespace backend {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SetPushConstantsCmd {
|
struct SetPushConstantsCmd {
|
||||||
nxt::ShaderStageBit stage;
|
nxt::ShaderStageBit stages;
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
};
|
};
|
||||||
|
|
|
@ -314,7 +314,7 @@ namespace opengl {
|
||||||
int32_t* valuesInt = reinterpret_cast<int32_t*>(valuesUInt);
|
int32_t* valuesInt = reinterpret_cast<int32_t*>(valuesUInt);
|
||||||
float* valuesFloat = reinterpret_cast<float*>(valuesUInt);
|
float* valuesFloat = reinterpret_cast<float*>(valuesUInt);
|
||||||
|
|
||||||
for (auto stage : IterateStages(cmd->stage)) {
|
for (auto stage : IterateStages(cmd->stages)) {
|
||||||
const auto& pushConstants = lastPipeline->GetPushConstants(stage);
|
const auto& pushConstants = lastPipeline->GetPushConstants(stage);
|
||||||
const auto& glPushConstants = lastGLPipeline->GetGLPushConstants(stage);
|
const auto& glPushConstants = lastGLPipeline->GetGLPushConstants(stage);
|
||||||
for (size_t i = 0; i < cmd->count; i++) {
|
for (size_t i = 0; i < cmd->count; i++) {
|
||||||
|
|
Loading…
Reference in New Issue