mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-14 07:36:15 +00:00
Remove the concept of push constants
BUG=dawn:14 Change-Id: I20587081ec806034ce4f90457c3d475a6fbe834d Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/7180 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
committed by
Commit Bot service account
parent
839053b90c
commit
8dfc593eb7
@@ -138,77 +138,6 @@ namespace dawn_native { namespace opengl {
|
||||
}
|
||||
}
|
||||
|
||||
// Push constants are implemented using OpenGL uniforms, however they aren't part of the
|
||||
// global OpenGL state but are part of the program state instead. This means that we have to
|
||||
// reapply push constants on pipeline change.
|
||||
//
|
||||
// This structure tracks the current values of push constants as well as dirty bits for push
|
||||
// constants that should be applied before the next draw or dispatch.
|
||||
class PushConstantTracker {
|
||||
public:
|
||||
PushConstantTracker() {
|
||||
for (auto stage : IterateStages(kAllStages)) {
|
||||
mValues[stage].fill(0);
|
||||
// No need to set dirty bits as a pipeline will be set before the next operation
|
||||
// using push constants.
|
||||
}
|
||||
}
|
||||
|
||||
void OnSetPushConstants(dawn::ShaderStageBit stages,
|
||||
uint32_t count,
|
||||
uint32_t offset,
|
||||
const uint32_t* data) {
|
||||
for (auto stage : IterateStages(stages)) {
|
||||
memcpy(&mValues[stage][offset], data, count * sizeof(uint32_t));
|
||||
|
||||
// Use 64 bit masks and make sure there are no shift UB
|
||||
static_assert(kMaxPushConstants <= 8 * sizeof(unsigned long long) - 1, "");
|
||||
mDirtyBits[stage] |= ((1ull << count) - 1ull) << offset;
|
||||
}
|
||||
}
|
||||
|
||||
void OnSetPipeline(PipelineBase* pipeline) {
|
||||
for (auto stage : IterateStages(kAllStages)) {
|
||||
mDirtyBits[stage] = pipeline->GetPushConstants(stage).mask;
|
||||
}
|
||||
}
|
||||
|
||||
void Apply(PipelineBase* pipeline, PipelineGL* glPipeline) {
|
||||
for (auto stage : IterateStages(kAllStages)) {
|
||||
const auto& pushConstants = pipeline->GetPushConstants(stage);
|
||||
const auto& glPushConstants = glPipeline->GetGLPushConstants(stage);
|
||||
|
||||
for (uint32_t constant :
|
||||
IterateBitSet(mDirtyBits[stage] & pushConstants.mask)) {
|
||||
GLint location = glPushConstants[constant];
|
||||
switch (pushConstants.types[constant]) {
|
||||
case PushConstantType::Int:
|
||||
glUniform1i(location,
|
||||
*reinterpret_cast<GLint*>(&mValues[stage][constant]));
|
||||
break;
|
||||
case PushConstantType::UInt:
|
||||
glUniform1ui(location,
|
||||
*reinterpret_cast<GLuint*>(&mValues[stage][constant]));
|
||||
break;
|
||||
case PushConstantType::Float:
|
||||
float value;
|
||||
// Use a memcpy to avoid strict-aliasing warnings, even if it is
|
||||
// still technically undefined behavior.
|
||||
memcpy(&value, &mValues[stage][constant], sizeof(value));
|
||||
glUniform1f(location, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mDirtyBits[stage].reset();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
PerStage<std::array<uint32_t, kMaxPushConstants>> mValues;
|
||||
PerStage<std::bitset<kMaxPushConstants>> mDirtyBits;
|
||||
};
|
||||
|
||||
// Vertex buffers and index buffers are implemented as part of an OpenGL VAO that
|
||||
// corresponds to an VertexInput. On the contrary in Dawn they are part of the global state.
|
||||
// This means that we have to re-apply these buffers on an VertexInput change.
|
||||
@@ -555,7 +484,6 @@ namespace dawn_native { namespace opengl {
|
||||
}
|
||||
|
||||
void CommandBuffer::ExecuteComputePass() {
|
||||
PushConstantTracker pushConstants;
|
||||
ComputePipeline* lastPipeline = nullptr;
|
||||
|
||||
Command type;
|
||||
@@ -568,7 +496,6 @@ namespace dawn_native { namespace opengl {
|
||||
|
||||
case Command::Dispatch: {
|
||||
DispatchCmd* dispatch = mCommands.NextCommand<DispatchCmd>();
|
||||
pushConstants.Apply(lastPipeline, lastPipeline);
|
||||
glDispatchCompute(dispatch->x, dispatch->y, dispatch->z);
|
||||
// TODO(cwallez@chromium.org): add barriers to the API
|
||||
glMemoryBarrier(GL_ALL_BARRIER_BITS);
|
||||
@@ -577,15 +504,7 @@ namespace dawn_native { namespace opengl {
|
||||
case Command::SetComputePipeline: {
|
||||
SetComputePipelineCmd* cmd = mCommands.NextCommand<SetComputePipelineCmd>();
|
||||
lastPipeline = ToBackend(cmd->pipeline).Get();
|
||||
|
||||
lastPipeline->ApplyNow();
|
||||
pushConstants.OnSetPipeline(lastPipeline);
|
||||
} break;
|
||||
|
||||
case Command::SetPushConstants: {
|
||||
SetPushConstantsCmd* cmd = mCommands.NextCommand<SetPushConstantsCmd>();
|
||||
uint32_t* data = mCommands.NextData<uint32_t>(cmd->count);
|
||||
pushConstants.OnSetPushConstants(cmd->stages, cmd->count, cmd->offset, data);
|
||||
} break;
|
||||
|
||||
case Command::SetBindGroup: {
|
||||
@@ -732,7 +651,6 @@ namespace dawn_native { namespace opengl {
|
||||
RenderPipeline* lastPipeline = nullptr;
|
||||
uint64_t indexBufferBaseOffset = 0;
|
||||
|
||||
PushConstantTracker pushConstants;
|
||||
InputBufferTracker inputBuffers;
|
||||
|
||||
Command type;
|
||||
@@ -751,7 +669,6 @@ namespace dawn_native { namespace opengl {
|
||||
|
||||
case Command::Draw: {
|
||||
DrawCmd* draw = mCommands.NextCommand<DrawCmd>();
|
||||
pushConstants.Apply(lastPipeline, lastPipeline);
|
||||
inputBuffers.Apply();
|
||||
|
||||
if (draw->firstInstance > 0) {
|
||||
@@ -768,7 +685,6 @@ namespace dawn_native { namespace opengl {
|
||||
|
||||
case Command::DrawIndexed: {
|
||||
DrawIndexedCmd* draw = mCommands.NextCommand<DrawIndexedCmd>();
|
||||
pushConstants.Apply(lastPipeline, lastPipeline);
|
||||
inputBuffers.Apply();
|
||||
|
||||
dawn::IndexFormat indexFormat =
|
||||
@@ -805,16 +721,9 @@ namespace dawn_native { namespace opengl {
|
||||
lastPipeline = ToBackend(cmd->pipeline).Get();
|
||||
lastPipeline->ApplyNow(persistentPipelineState);
|
||||
|
||||
pushConstants.OnSetPipeline(lastPipeline);
|
||||
inputBuffers.OnSetPipeline(lastPipeline);
|
||||
} break;
|
||||
|
||||
case Command::SetPushConstants: {
|
||||
SetPushConstantsCmd* cmd = mCommands.NextCommand<SetPushConstantsCmd>();
|
||||
uint32_t* data = mCommands.NextData<uint32_t>(cmd->count);
|
||||
pushConstants.OnSetPushConstants(cmd->stages, cmd->count, cmd->offset, data);
|
||||
} break;
|
||||
|
||||
case Command::SetStencilReference: {
|
||||
SetStencilReferenceCmd* cmd = mCommands.NextCommand<SetStencilReferenceCmd>();
|
||||
persistentPipelineState.SetStencilReference(cmd->reference);
|
||||
|
||||
@@ -70,29 +70,6 @@ namespace dawn_native { namespace opengl {
|
||||
return shader;
|
||||
};
|
||||
|
||||
auto FillPushConstants = [](const ShaderModule* module, GLPushConstantInfo* info,
|
||||
GLuint program) {
|
||||
const auto& moduleInfo = module->GetPushConstants();
|
||||
for (uint32_t i = 0; i < moduleInfo.names.size(); i++) {
|
||||
(*info)[i] = -1;
|
||||
|
||||
unsigned int size = moduleInfo.sizes[i];
|
||||
if (size == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GLint location = glGetUniformLocation(program, moduleInfo.names[i].c_str());
|
||||
if (location == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (uint32_t offset = 0; offset < size; offset++) {
|
||||
(*info)[i + offset] = location + offset;
|
||||
}
|
||||
i += size - 1;
|
||||
}
|
||||
};
|
||||
|
||||
mProgram = glCreateProgram();
|
||||
|
||||
dawn::ShaderStageBit activeStages = dawn::ShaderStageBit::None;
|
||||
@@ -123,10 +100,6 @@ namespace dawn_native { namespace opengl {
|
||||
}
|
||||
}
|
||||
|
||||
for (dawn::ShaderStage stage : IterateStages(activeStages)) {
|
||||
FillPushConstants(modules[stage], &mGlPushConstants[stage], mProgram);
|
||||
}
|
||||
|
||||
glUseProgram(mProgram);
|
||||
|
||||
// The uniforms are part of the program state so we can pre-bind buffer units, texture units
|
||||
@@ -200,11 +173,6 @@ namespace dawn_native { namespace opengl {
|
||||
}
|
||||
}
|
||||
|
||||
const PipelineGL::GLPushConstantInfo& PipelineGL::GetGLPushConstants(
|
||||
dawn::ShaderStage stage) const {
|
||||
return mGlPushConstants[stage];
|
||||
}
|
||||
|
||||
const std::vector<GLuint>& PipelineGL::GetTextureUnitsForSampler(GLuint index) const {
|
||||
ASSERT(index < mUnitsForSamplers.size());
|
||||
return mUnitsForSamplers[index];
|
||||
|
||||
@@ -34,11 +34,9 @@ namespace dawn_native { namespace opengl {
|
||||
|
||||
void Initialize(const PipelineLayout* layout, const PerStage<const ShaderModule*>& modules);
|
||||
|
||||
using GLPushConstantInfo = std::array<GLint, kMaxPushConstants>;
|
||||
using BindingLocations =
|
||||
std::array<std::array<GLint, kMaxBindingsPerGroup>, kMaxBindGroups>;
|
||||
|
||||
const GLPushConstantInfo& GetGLPushConstants(dawn::ShaderStage stage) const;
|
||||
const std::vector<GLuint>& GetTextureUnitsForSampler(GLuint index) const;
|
||||
const std::vector<GLuint>& GetTextureUnitsForTextureView(GLuint index) const;
|
||||
GLuint GetProgramHandle() const;
|
||||
@@ -47,7 +45,6 @@ namespace dawn_native { namespace opengl {
|
||||
|
||||
private:
|
||||
GLuint mProgram;
|
||||
PerStage<GLPushConstantInfo> mGlPushConstants;
|
||||
std::vector<std::vector<GLuint>> mUnitsForSamplers;
|
||||
std::vector<std::vector<GLuint>> mUnitsForTextures;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user