Dawn: implement textures & samplers.
Add samplers to Dawn binding group layout. Convert filter modes from Gr to Dawn. Rename fUniformBindGroup to fBindGroup (since it does more than uniforms now). Split combined samplers into separate textures and samplers bindings; recombine in the shader with makeSampler(). Create complete bind group layout before creating UBOs. Implement scissor rect. Set blend color in command buffer. Pass shader caps to SkSL. Enable flat interpolation, integer support, derivative support in Dawn Caps. Reduce the Dawn caps to 6 fragment/sampler combos. Add support for Int (1) vertex format. Change-Id: Id5e9060855f0dfc8c071f84ea6c456aba2a72b35 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/233977 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
This commit is contained in:
parent
4bdcbc2704
commit
170d9905cc
@ -8,12 +8,22 @@
|
||||
#include "src/gpu/dawn/GrDawnCaps.h"
|
||||
|
||||
GrDawnCaps::GrDawnCaps(const GrContextOptions& contextOptions) : INHERITED(contextOptions) {
|
||||
fMipMapSupport = true;
|
||||
fBufferMapThreshold = SK_MaxS32; // FIXME: get this from Dawn?
|
||||
fShaderCaps.reset(new GrShaderCaps(contextOptions));
|
||||
fMaxTextureSize = 2048; // FIXME
|
||||
fMaxTextureSize = fMaxRenderTargetSize = 4096; // FIXME
|
||||
fMaxVertexAttributes = 16; // FIXME
|
||||
fClampToBorderSupport = false;
|
||||
fPerformPartialClearsAsDraws = true;
|
||||
|
||||
fShaderCaps->fFlatInterpolationSupport = true;
|
||||
fShaderCaps->fIntegerSupport = true;
|
||||
// FIXME: each fragment sampler takes two binding slots in Dawn (sampler + texture). Limit to
|
||||
// 6 * 2 = 12, since kMaxBindingsPerGroup is 16 in Dawn, and we need to keep a few for
|
||||
// non-texture bindings. Eventually, we may be able to increase kMaxBindingsPerGroup in Dawn.
|
||||
fShaderCaps->fMaxFragmentSamplers = 6;
|
||||
fShaderCaps->fShaderDerivativeSupport = true;
|
||||
|
||||
this->applyOptionsOverrides(contextOptions);
|
||||
fShaderCaps->applyOptionsOverrides(contextOptions);
|
||||
}
|
||||
|
@ -23,7 +23,10 @@
|
||||
#include "src/gpu/dawn/GrDawnRenderTarget.h"
|
||||
#include "src/gpu/dawn/GrDawnStencilAttachment.h"
|
||||
#include "src/gpu/dawn/GrDawnTexture.h"
|
||||
#include "src/gpu/dawn/GrDawnUtil.h"
|
||||
|
||||
#include "src/core/SkAutoMalloc.h"
|
||||
#include "src/core/SkMipMap.h"
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
|
||||
#if !defined(SK_BUILD_FOR_WIN)
|
||||
@ -222,15 +225,102 @@ GrStencilAttachment* GrDawnGpu::createStencilAttachmentForRenderTarget(const GrR
|
||||
}
|
||||
|
||||
GrBackendTexture GrDawnGpu::createBackendTexture(int width, int height,
|
||||
const GrBackendFormat& format,
|
||||
const GrBackendFormat& backendFormat,
|
||||
GrMipMapped mipMapped,
|
||||
GrRenderable renderable,
|
||||
const void* pixels,
|
||||
size_t rowBytes,
|
||||
const SkColor4f* color,
|
||||
GrProtected isProtected) {
|
||||
SkASSERT(!"unimplemented");
|
||||
return GrBackendTexture();
|
||||
dawn::TextureFormat format;
|
||||
if (!backendFormat.asDawnFormat(&format)) {
|
||||
return GrBackendTexture();
|
||||
}
|
||||
|
||||
GrPixelConfig config = GrDawnFormatToPixelConfig(format);
|
||||
|
||||
if (width > this->caps()->maxTextureSize() || height > this->caps()->maxTextureSize()) {
|
||||
return GrBackendTexture();
|
||||
}
|
||||
|
||||
// Currently we don't support uploading pixel data when mipped.
|
||||
if (pixels && GrMipMapped::kYes == mipMapped) {
|
||||
return GrBackendTexture();
|
||||
}
|
||||
|
||||
dawn::TextureDescriptor desc;
|
||||
desc.usage =
|
||||
dawn::TextureUsageBit::Sampled |
|
||||
dawn::TextureUsageBit::CopySrc |
|
||||
dawn::TextureUsageBit::CopyDst;
|
||||
|
||||
if (GrRenderable::kYes == renderable) {
|
||||
desc.usage |= dawn::TextureUsageBit::OutputAttachment;
|
||||
}
|
||||
|
||||
desc.size.width = width;
|
||||
desc.size.height = height;
|
||||
desc.size.depth = 1;
|
||||
desc.format = format;
|
||||
|
||||
// Figure out the number of mip levels.
|
||||
if (GrMipMapped::kYes == mipMapped) {
|
||||
desc.mipLevelCount = SkMipMap::ComputeLevelCount(width, height) + 1;
|
||||
}
|
||||
|
||||
dawn::Texture tex = this->device().CreateTexture(&desc);
|
||||
|
||||
size_t bpp = GrBytesPerPixel(config);
|
||||
size_t baseLayerSize = bpp * width * height;
|
||||
SkAutoMalloc defaultStorage(baseLayerSize);
|
||||
if (!pixels) {
|
||||
// Fill in the texture with all zeros so we don't have random garbage
|
||||
pixels = defaultStorage.get();
|
||||
memset(defaultStorage.get(), 0, baseLayerSize);
|
||||
}
|
||||
dawn::Device device = this->device();
|
||||
dawn::CommandEncoder copyEncoder = fDevice.CreateCommandEncoder();
|
||||
int w = width, h = height;
|
||||
for (uint32_t i = 0; i < desc.mipLevelCount; i++) {
|
||||
size_t origRowBytes = bpp * w;
|
||||
size_t rowBytes = GrDawnRoundRowBytes(origRowBytes);
|
||||
size_t size = rowBytes * h;
|
||||
dawn::BufferDescriptor bufferDesc;
|
||||
bufferDesc.size = size;
|
||||
bufferDesc.usage = dawn::BufferUsageBit::CopySrc | dawn::BufferUsageBit::CopyDst;
|
||||
dawn::Buffer buffer = this->device().CreateBuffer(&bufferDesc);
|
||||
const uint8_t* src = static_cast<const uint8_t*>(pixels);
|
||||
if (rowBytes == origRowBytes) {
|
||||
buffer.SetSubData(0, size, src);
|
||||
} else {
|
||||
uint32_t offset = 0;
|
||||
for (int row = 0; row < h; row++) {
|
||||
buffer.SetSubData(offset, origRowBytes, src);
|
||||
offset += rowBytes;
|
||||
src += origRowBytes;
|
||||
}
|
||||
}
|
||||
dawn::BufferCopyView srcBuffer;
|
||||
srcBuffer.buffer = buffer;
|
||||
srcBuffer.offset = 0;
|
||||
srcBuffer.rowPitch = rowBytes;
|
||||
srcBuffer.imageHeight = h;
|
||||
dawn::TextureCopyView dstTexture;
|
||||
dstTexture.texture = tex;
|
||||
dstTexture.mipLevel = i;
|
||||
dstTexture.origin = {0, 0, 0};
|
||||
dawn::Extent3D copySize = {(uint32_t) w, (uint32_t) h, 1};
|
||||
copyEncoder.CopyBufferToTexture(&srcBuffer, &dstTexture, ©Size);
|
||||
w = SkTMax(1, w / 2);
|
||||
h = SkTMax(1, h / 2);
|
||||
}
|
||||
dawn::CommandBuffer cmdBuf = copyEncoder.Finish();
|
||||
fQueue.Submit(1, &cmdBuf);
|
||||
GrDawnImageInfo info;
|
||||
info.fTexture = tex;
|
||||
info.fFormat = desc.format;
|
||||
info.fLevelCount = desc.mipLevelCount;
|
||||
return GrBackendTexture(width, height, info);
|
||||
}
|
||||
|
||||
void GrDawnGpu::deleteBackendTexture(const GrBackendTexture& tex) {
|
||||
|
@ -84,13 +84,19 @@ GrDawnGpuTextureCommandBuffer::~GrDawnGpuTextureCommandBuffer() {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
dawn::LoadOp to_dawn_load_op(GrLoadOp loadOp) {
|
||||
static dawn::LoadOp to_dawn_load_op(GrLoadOp loadOp) {
|
||||
switch (loadOp) {
|
||||
case GrLoadOp::kLoad:
|
||||
return dawn::LoadOp::Load;
|
||||
case GrLoadOp::kDiscard:
|
||||
// Use LoadOp::Load to emulate DontCare.
|
||||
// Dawn doesn't have DontCare, for security reasons.
|
||||
// Load should be equivalent to DontCare for desktop; Clear would
|
||||
// probably be better for tilers. If Dawn does add DontCare
|
||||
// as an extension, use it here.
|
||||
return dawn::LoadOp::Load;
|
||||
case GrLoadOp::kClear:
|
||||
return dawn::LoadOp::Clear;
|
||||
case GrLoadOp::kDiscard:
|
||||
default:
|
||||
SK_ABORT("Invalid LoadOp");
|
||||
}
|
||||
@ -255,6 +261,8 @@ static dawn::VertexFormat to_dawn_vertex_format(GrVertexAttribType type) {
|
||||
return dawn::VertexFormat::Float4;
|
||||
case kUShort2_GrVertexAttribType:
|
||||
return dawn::VertexFormat::UShort2;
|
||||
case kInt_GrVertexAttribType:
|
||||
return dawn::VertexFormat::Int;
|
||||
case kUByte4_norm_GrVertexAttribType:
|
||||
return dawn::VertexFormat::UChar4Norm;
|
||||
default:
|
||||
@ -282,6 +290,24 @@ static dawn::PrimitiveTopology to_dawn_primitive_topology(GrPrimitiveType primit
|
||||
}
|
||||
}
|
||||
|
||||
void GrDawnGpuRTCommandBuffer::setScissorState(
|
||||
const GrPipeline& pipeline,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
const GrPipeline::DynamicStateArrays* dynamicStateArrays) {
|
||||
SkIRect rect;
|
||||
if (pipeline.isScissorEnabled()) {
|
||||
constexpr SkIRect kBogusScissor{0, 0, 1, 1};
|
||||
rect = fixedDynamicState ? fixedDynamicState->fScissorRect : kBogusScissor;
|
||||
if (kBottomLeft_GrSurfaceOrigin == fOrigin) {
|
||||
rect.setXYWH(rect.x(), fRenderTarget->height() - rect.bottom(),
|
||||
rect.width(), rect.height());
|
||||
}
|
||||
} else {
|
||||
rect = SkIRect::MakeWH(fRenderTarget->width(), fRenderTarget->height());
|
||||
}
|
||||
fPassEncoder.SetScissorRect(rect.x(), rect.y(), rect.width(), rect.height());
|
||||
}
|
||||
|
||||
void GrDawnGpuRTCommandBuffer::applyState(const GrPipeline& pipeline,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
@ -378,10 +404,15 @@ void GrDawnGpuRTCommandBuffer::applyState(const GrPipeline& pipeline,
|
||||
rpDesc.colorStates = colorStates;
|
||||
dawn::RenderPipeline renderPipeline = fGpu->device().CreateRenderPipeline(&rpDesc);
|
||||
fPassEncoder.SetPipeline(renderPipeline);
|
||||
fPassEncoder.SetBindGroup(0, program->fUniformBindGroup, 0, nullptr);
|
||||
fPassEncoder.SetBindGroup(0, program->fBindGroup, 0, nullptr);
|
||||
if (pipeline.isStencilEnabled()) {
|
||||
fPassEncoder.SetStencilReference(pipeline.getUserStencil()->fFront.fRef);
|
||||
}
|
||||
GrXferProcessor::BlendInfo blendInfo = pipeline.getXferProcessor().getBlendInfo();
|
||||
const float* c = blendInfo.fBlendConstant.vec();
|
||||
dawn::Color color{c[0], c[1], c[2], c[3]};
|
||||
fPassEncoder.SetBlendColor(&color);
|
||||
this->setScissorState(pipeline, fixedDynamicState, dynamicStateArrays);
|
||||
}
|
||||
|
||||
void GrDawnGpuRTCommandBuffer::onDraw(const GrPrimitiveProcessor& primProc,
|
||||
|
@ -64,6 +64,9 @@ public:
|
||||
private:
|
||||
GrGpu* gpu() override;
|
||||
|
||||
void setScissorState(const GrPipeline&,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
const GrPipeline::DynamicStateArrays* dynamicStateArrays);
|
||||
void applyState(const GrPipeline& pipeline,
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrTextureProxy* const primProcProxies[],
|
||||
|
@ -11,11 +11,13 @@
|
||||
#include "src/gpu/GrShaderUtils.h"
|
||||
#include "src/gpu/GrStencilSettings.h"
|
||||
#include "src/gpu/dawn/GrDawnGpu.h"
|
||||
#include "src/gpu/dawn/GrDawnTexture.h"
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
|
||||
static SkSL::String sksl_to_spirv(const GrDawnGpu* gpu, const char* shaderString,
|
||||
SkSL::Program::Kind kind, SkSL::Program::Inputs* inputs) {
|
||||
SkSL::Program::Settings settings;
|
||||
settings.fCaps = gpu->caps()->shaderCaps();
|
||||
std::unique_ptr<SkSL::Program> program = gpu->shaderCompiler()->convertProgram(
|
||||
kind,
|
||||
shaderString,
|
||||
@ -149,6 +151,35 @@ static dawn::StencilOperation to_dawn_stencil_operation(GrStencilOp op) {
|
||||
}
|
||||
}
|
||||
|
||||
static dawn::FilterMode to_dawn_filter_mode(GrSamplerState::Filter filter) {
|
||||
switch (filter) {
|
||||
case GrSamplerState::Filter::kNearest:
|
||||
return dawn::FilterMode::Nearest;
|
||||
case GrSamplerState::Filter::kBilerp:
|
||||
case GrSamplerState::Filter::kMipMap:
|
||||
return dawn::FilterMode::Linear;
|
||||
default:
|
||||
SkASSERT(!"unsupported filter mode");
|
||||
return dawn::FilterMode::Nearest;
|
||||
}
|
||||
}
|
||||
|
||||
static dawn::AddressMode to_dawn_address_mode(GrSamplerState::WrapMode wrapMode) {
|
||||
switch (wrapMode) {
|
||||
case GrSamplerState::WrapMode::kClamp:
|
||||
return dawn::AddressMode::ClampToEdge;
|
||||
case GrSamplerState::WrapMode::kClampToBorder:
|
||||
// TODO: unsupported
|
||||
return dawn::AddressMode::ClampToEdge;
|
||||
case GrSamplerState::WrapMode::kRepeat:
|
||||
return dawn::AddressMode::Repeat;
|
||||
case GrSamplerState::WrapMode::kMirrorRepeat:
|
||||
return dawn::AddressMode::MirrorRepeat;
|
||||
}
|
||||
SkASSERT(!"unsupported address mode");
|
||||
return dawn::AddressMode::ClampToEdge;
|
||||
}
|
||||
|
||||
static dawn::ColorStateDescriptor create_color_state(const GrDawnGpu* gpu,
|
||||
const GrPipeline& pipeline,
|
||||
dawn::TextureFormat colorFormat) {
|
||||
@ -215,6 +246,19 @@ static dawn::DepthStencilStateDescriptor create_depth_stencil_state(
|
||||
return state;
|
||||
}
|
||||
|
||||
static dawn::Sampler create_sampler(const GrDawnGpu* gpu, const GrSamplerState& samplerState) {
|
||||
dawn::SamplerDescriptor desc;
|
||||
desc.addressModeU = to_dawn_address_mode(samplerState.wrapModeX());
|
||||
desc.addressModeV = to_dawn_address_mode(samplerState.wrapModeY());
|
||||
desc.addressModeW = dawn::AddressMode::ClampToEdge;
|
||||
desc.magFilter = desc.minFilter = to_dawn_filter_mode(samplerState.filter());
|
||||
desc.mipmapFilter = dawn::FilterMode::Linear;
|
||||
desc.lodMinClamp = 0.0f;
|
||||
desc.lodMaxClamp = 1000.0f;
|
||||
desc.compare = dawn::CompareFunction::Never;
|
||||
return gpu->device().CreateSampler(&desc);
|
||||
}
|
||||
|
||||
static dawn::BindGroupBinding make_bind_group_binding(uint32_t binding, const dawn::Buffer& buffer,
|
||||
uint32_t offset, uint32_t size, const
|
||||
dawn::Sampler& sampler,
|
||||
@ -234,6 +278,16 @@ static dawn::BindGroupBinding make_bind_group_binding(uint32_t binding, const da
|
||||
return make_bind_group_binding(binding, buffer, offset, size, nullptr, nullptr);
|
||||
}
|
||||
|
||||
static dawn::BindGroupBinding make_bind_group_binding(uint32_t binding,
|
||||
const dawn::Sampler& sampler) {
|
||||
return make_bind_group_binding(binding, nullptr, 0, 0, sampler, nullptr);
|
||||
}
|
||||
|
||||
static dawn::BindGroupBinding make_bind_group_binding(uint32_t binding,
|
||||
const dawn::TextureView& textureView) {
|
||||
return make_bind_group_binding(binding, nullptr, 0, 0, nullptr, textureView);
|
||||
}
|
||||
|
||||
sk_sp<GrDawnProgram> GrDawnProgramBuilder::Build(GrDawnGpu* gpu,
|
||||
GrRenderTarget* renderTarget,
|
||||
GrSurfaceOrigin origin,
|
||||
@ -273,40 +327,74 @@ sk_sp<GrDawnProgram> GrDawnProgramBuilder::Build(GrDawnGpu* gpu,
|
||||
result->fFragmentProcessorCnt = builder.fFragmentProcessorCnt;
|
||||
std::vector<dawn::BindGroupLayoutBinding> layoutBindings;
|
||||
std::vector<dawn::BindGroupBinding> bindings;
|
||||
|
||||
if (0 != geometryUniformSize) {
|
||||
layoutBindings.push_back({ GrDawnUniformHandler::kGeometryBinding,
|
||||
dawn::ShaderStageBit::Vertex,
|
||||
dawn::BindingType::UniformBuffer});
|
||||
}
|
||||
if (0 != fragmentUniformSize) {
|
||||
layoutBindings.push_back({ GrDawnUniformHandler::kFragBinding,
|
||||
dawn::ShaderStageBit::Fragment,
|
||||
dawn::BindingType::UniformBuffer});
|
||||
}
|
||||
uint32_t binding = GrDawnUniformHandler::kSamplerBindingBase;
|
||||
for (int i = 0; i < builder.fUniformHandler.fSamplers.count(); ++i) {
|
||||
layoutBindings.push_back({ binding++, dawn::ShaderStageBit::Fragment,
|
||||
dawn::BindingType::Sampler});
|
||||
layoutBindings.push_back({ binding++, dawn::ShaderStageBit::Fragment,
|
||||
dawn::BindingType::SampledTexture});
|
||||
}
|
||||
dawn::BindGroupLayoutDescriptor bindGroupLayoutDesc;
|
||||
bindGroupLayoutDesc.bindingCount = layoutBindings.size();
|
||||
bindGroupLayoutDesc.bindings = layoutBindings.data();
|
||||
auto bindGroupLayout = gpu->device().CreateBindGroupLayout(&bindGroupLayoutDesc);
|
||||
dawn::PipelineLayoutDescriptor pipelineLayoutDesc;
|
||||
pipelineLayoutDesc.bindGroupLayoutCount = 1;
|
||||
pipelineLayoutDesc.bindGroupLayouts = &bindGroupLayout;
|
||||
result->fPipelineLayout = gpu->device().CreatePipelineLayout(&pipelineLayoutDesc);
|
||||
if (0 != geometryUniformSize) {
|
||||
dawn::BufferDescriptor desc;
|
||||
desc.usage = dawn::BufferUsageBit::Uniform | dawn::BufferUsageBit::CopyDst;
|
||||
desc.size = geometryUniformSize;
|
||||
result->fGeometryUniformBuffer = gpu->device().CreateBuffer(&desc);
|
||||
bindings.push_back(make_bind_group_binding(0, result->fGeometryUniformBuffer, 0,
|
||||
geometryUniformSize));
|
||||
layoutBindings.push_back({ 0, dawn::ShaderStageBit::Vertex,
|
||||
dawn::BindingType::UniformBuffer});
|
||||
bindings.push_back(make_bind_group_binding(GrDawnUniformHandler::kGeometryBinding,
|
||||
result->fGeometryUniformBuffer,
|
||||
0, geometryUniformSize));
|
||||
}
|
||||
if (0 != fragmentUniformSize) {
|
||||
dawn::BufferDescriptor desc;
|
||||
desc.usage = dawn::BufferUsageBit::Uniform | dawn::BufferUsageBit::CopyDst;
|
||||
desc.size = fragmentUniformSize;
|
||||
result->fFragmentUniformBuffer = gpu->device().CreateBuffer(&desc);
|
||||
bindings.push_back(make_bind_group_binding(1, result->fFragmentUniformBuffer, 0,
|
||||
fragmentUniformSize));
|
||||
layoutBindings.push_back({ 1, dawn::ShaderStageBit::Fragment,
|
||||
dawn::BindingType::UniformBuffer});
|
||||
bindings.push_back(make_bind_group_binding(GrDawnUniformHandler::kFragBinding,
|
||||
result->fFragmentUniformBuffer,
|
||||
0, fragmentUniformSize));
|
||||
}
|
||||
dawn::BindGroupLayoutDescriptor bindGroupLayoutDesc;
|
||||
bindGroupLayoutDesc.bindingCount = layoutBindings.size();
|
||||
bindGroupLayoutDesc.bindings = layoutBindings.data();
|
||||
auto bindGroupLayout = gpu->device().CreateBindGroupLayout(&bindGroupLayoutDesc);
|
||||
dawn::BindGroupDescriptor descriptor;
|
||||
descriptor.layout = bindGroupLayout;
|
||||
descriptor.bindingCount = bindings.size();
|
||||
descriptor.bindings = bindings.data();
|
||||
result->fUniformBindGroup = gpu->device().CreateBindGroup(&descriptor);
|
||||
dawn::PipelineLayoutDescriptor pipelineLayoutDesc;
|
||||
pipelineLayoutDesc.bindGroupLayoutCount = 1;
|
||||
pipelineLayoutDesc.bindGroupLayouts = &bindGroupLayout;
|
||||
result->fPipelineLayout = gpu->device().CreatePipelineLayout(&pipelineLayoutDesc);
|
||||
binding = GrDawnUniformHandler::kSamplerBindingBase;
|
||||
for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
|
||||
dawn::Sampler sampler = create_sampler(gpu, primProc.textureSampler(i).samplerState());
|
||||
bindings.push_back(make_bind_group_binding(binding++, sampler));
|
||||
GrDawnTexture* tex = static_cast<GrDawnTexture*>(primProcProxies[i]->peekTexture());
|
||||
dawn::TextureView textureView = tex->textureView();
|
||||
bindings.push_back(make_bind_group_binding(binding++, textureView));
|
||||
}
|
||||
GrFragmentProcessor::Iter iter(pipeline);
|
||||
const GrFragmentProcessor* fp = iter.next();
|
||||
while (fp) {
|
||||
for (int i = 0; i < fp->numTextureSamplers(); ++i) {
|
||||
dawn::Sampler sampler = create_sampler(gpu, fp->textureSampler(i).samplerState());
|
||||
bindings.push_back(make_bind_group_binding(binding++, sampler));
|
||||
GrDawnTexture* tex = static_cast<GrDawnTexture*>(fp->textureSampler(i).peekTexture());
|
||||
dawn::TextureView textureView = tex->textureView();
|
||||
bindings.push_back(make_bind_group_binding(binding++, textureView));
|
||||
}
|
||||
fp = iter.next();
|
||||
}
|
||||
dawn::BindGroupDescriptor bindGroupDescriptor;
|
||||
bindGroupDescriptor.layout = bindGroupLayout;
|
||||
bindGroupDescriptor.bindingCount = bindings.size();
|
||||
bindGroupDescriptor.bindings = bindings.data();
|
||||
result->fBindGroup = gpu->device().CreateBindGroup(&bindGroupDescriptor);
|
||||
result->fBuiltinUniformHandles = builder.fUniformHandles;
|
||||
result->fColorState = create_color_state(gpu, pipeline, colorFormat);
|
||||
GrStencilSettings stencil;
|
||||
|
@ -63,7 +63,7 @@ struct GrDawnProgram : public SkRefCnt {
|
||||
dawn::Buffer fGeometryUniformBuffer;
|
||||
dawn::Buffer fFragmentUniformBuffer;
|
||||
dawn::PipelineLayout fPipelineLayout;
|
||||
dawn::BindGroup fUniformBindGroup;
|
||||
dawn::BindGroup fBindGroup;
|
||||
dawn::ColorStateDescriptor fColorState;
|
||||
dawn::DepthStencilStateDescriptor fDepthStencilState;
|
||||
GrDawnProgramDataManager fDataManager;
|
||||
|
@ -11,6 +11,8 @@
|
||||
GrDawnUniformHandler::GrDawnUniformHandler(GrGLSLProgramBuilder* program)
|
||||
: INHERITED(program)
|
||||
, fUniforms(kUniformsPerBlock)
|
||||
, fSamplers(kUniformsPerBlock)
|
||||
, fTextures(kUniformsPerBlock)
|
||||
{
|
||||
}
|
||||
|
||||
@ -236,24 +238,62 @@ GrGLSLUniformHandler::SamplerHandle GrDawnUniformHandler::addSampler(const GrTex
|
||||
const GrSwizzle& swizzle,
|
||||
const char* name,
|
||||
const GrShaderCaps* caps) {
|
||||
SkASSERT(!"unimplemented");
|
||||
SkASSERT(name && strlen(name));
|
||||
SkString mangleName;
|
||||
char prefix = 's';
|
||||
fProgramBuilder->nameVariable(&mangleName, prefix, name, true);
|
||||
|
||||
return GrGLSLUniformHandler::SamplerHandle(0);
|
||||
GrSLType samplerType = kSampler_GrSLType, textureType = kTexture2D_GrSLType;
|
||||
int binding = kSamplerBindingBase + fSamplers.count() * 2;
|
||||
UniformInfo& info = fSamplers.push_back();
|
||||
info.fVar.setType(samplerType);
|
||||
info.fVar.setTypeModifier(GrShaderVar::kUniform_TypeModifier);
|
||||
info.fVar.setName(mangleName);
|
||||
SkString layoutQualifier;
|
||||
layoutQualifier.appendf("set = 0, binding = %d", binding);
|
||||
info.fVar.addLayoutQualifier(layoutQualifier.c_str());
|
||||
info.fVisibility = kFragment_GrShaderFlag;
|
||||
info.fUBOOffset = 0;
|
||||
fSamplerSwizzles.push_back(swizzle);
|
||||
SkASSERT(fSamplerSwizzles.count() == fSamplers.count());
|
||||
|
||||
SkString mangleTexName;
|
||||
char texPrefix = 't';
|
||||
fProgramBuilder->nameVariable(&mangleTexName, texPrefix, name, true);
|
||||
UniformInfo& texInfo = fTextures.push_back();
|
||||
texInfo.fVar.setType(textureType);
|
||||
texInfo.fVar.setTypeModifier(GrShaderVar::kUniform_TypeModifier);
|
||||
texInfo.fVar.setName(mangleTexName);
|
||||
SkString texLayoutQualifier;
|
||||
texLayoutQualifier.appendf("set = 0, binding = %d", binding + 1);
|
||||
texInfo.fVar.addLayoutQualifier(texLayoutQualifier.c_str());
|
||||
texInfo.fVisibility = kFragment_GrShaderFlag;
|
||||
texInfo.fUBOOffset = 0;
|
||||
|
||||
SkString reference;
|
||||
reference.printf("makeSampler2D(%s, %s)", texInfo.fVar.getName().c_str(),
|
||||
info.fVar.getName().c_str());
|
||||
fSamplerReferences.push_back() = reference;
|
||||
return GrGLSLUniformHandler::SamplerHandle(fSamplers.count() - 1);
|
||||
}
|
||||
|
||||
const char* GrDawnUniformHandler::samplerVariable(
|
||||
GrGLSLUniformHandler::SamplerHandle handle) const {
|
||||
SkASSERT(!"unimplemented");
|
||||
return "";
|
||||
return fSamplerReferences[handle.toIndex()].c_str();
|
||||
}
|
||||
|
||||
GrSwizzle GrDawnUniformHandler::samplerSwizzle(GrGLSLUniformHandler::SamplerHandle handle) const {
|
||||
SkASSERT(!"unimplemented");
|
||||
return GrSwizzle();
|
||||
return fSamplerSwizzles[handle.toIndex()];
|
||||
}
|
||||
|
||||
void GrDawnUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString* out) const {
|
||||
for (int i = 0; i < fSamplers.count(); ++i) {
|
||||
if (fSamplers[i].fVisibility & visibility) {
|
||||
fSamplers[i].fVar.appendDecl(fProgramBuilder->shaderCaps(), out);
|
||||
out->append(";\n");
|
||||
fTextures[i].fVar.appendDecl(fProgramBuilder->shaderCaps(), out);
|
||||
out->append(";\n");
|
||||
}
|
||||
}
|
||||
SkString uniformsString;
|
||||
for (int i = 0; i < fUniforms.count(); ++i) {
|
||||
if (fUniforms[i].fVisibility & visibility) {
|
||||
@ -275,8 +315,8 @@ void GrDawnUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString
|
||||
uniformBinding = kFragBinding;
|
||||
stage = "fragment";
|
||||
}
|
||||
out->appendf("layout (set = %d, binding = %d) uniform %sUniformBuffer\n{\n",
|
||||
kUniformBufferBindGroup, uniformBinding, stage);
|
||||
out->appendf("layout (set = 0, binding = %d) uniform %sUniformBuffer\n{\n",
|
||||
uniformBinding, stage);
|
||||
out->appendf("%s\n};\n", uniformsString.c_str());
|
||||
}
|
||||
}
|
||||
|
@ -20,11 +20,6 @@ public:
|
||||
const GrShaderVar& getUniformVariable(UniformHandle u) const override;
|
||||
const char* getUniformCStr(UniformHandle u) const override;
|
||||
|
||||
enum {
|
||||
kUniformBufferBindGroup = 0,
|
||||
kSamplerBindGroup = 1,
|
||||
kTexelBufferBindGroup = 2,
|
||||
};
|
||||
struct UniformInfo {
|
||||
GrShaderVar fVar;
|
||||
int fUBOOffset;
|
||||
@ -34,6 +29,7 @@ public:
|
||||
enum {
|
||||
kGeometryBinding = 0,
|
||||
kFragBinding = 1,
|
||||
kSamplerBindingBase = 2,
|
||||
};
|
||||
|
||||
private:
|
||||
@ -51,8 +47,12 @@ private:
|
||||
int arrayCount,
|
||||
const char** outName) override;
|
||||
|
||||
GrShaderVar fDummyVar;
|
||||
UniformInfoArray fUniforms;
|
||||
UniformInfoArray fUniforms;
|
||||
UniformInfoArray fSamplers;
|
||||
UniformInfoArray fTextures;
|
||||
SkTArray<GrSwizzle> fSamplerSwizzles;
|
||||
SkTArray<SkString> fSamplerReferences;
|
||||
|
||||
uint32_t fCurrentGeometryUBOOffset = 0;
|
||||
uint32_t fCurrentFragmentUBOOffset = 0;
|
||||
|
||||
|
@ -40,6 +40,7 @@ bool GrPixelConfigToDawnFormat(GrPixelConfig config, dawn::TextureFormat* format
|
||||
*format = dawn::TextureFormat::BGRA8Unorm;
|
||||
return true;
|
||||
case kAlpha_8_GrPixelConfig:
|
||||
case kAlpha_8_as_Red_GrPixelConfig:
|
||||
*format = dawn::TextureFormat::R8Unorm;
|
||||
return true;
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user