Set up D3D textures and draw buffers
Change-Id: Ice6676acc33cc245ee62bea587181c1459dbba33 Bug: skia:9935 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/290829 Commit-Queue: Jim Van Verth <jvanverth@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
parent
682fca9299
commit
40b4de2dbd
@ -148,16 +148,6 @@ void GrD3DCommandList::copyTextureRegion(sk_sp<GrManagedResource> dst,
|
||||
fCommandList->CopyTextureRegion(dstLocation, dstX, dstY, 0, srcLocation, srcBox);
|
||||
}
|
||||
|
||||
void GrD3DCommandList::clearRenderTargetView(GrD3DRenderTarget* renderTarget,
|
||||
const SkPMColor4f& color,
|
||||
const GrFixedClip& clip) {
|
||||
this->addingWork();
|
||||
this->addResource(renderTarget->resource());
|
||||
fCommandList->ClearRenderTargetView(renderTarget->colorRenderTargetView(),
|
||||
color.vec(),
|
||||
0, NULL); // no cliprects for now
|
||||
}
|
||||
|
||||
void GrD3DCommandList::addingWork() {
|
||||
this->submitResourceBarriers();
|
||||
fHasWork = true;
|
||||
@ -218,6 +208,51 @@ void GrD3DDirectCommandList::setViewports(unsigned int numViewports,
|
||||
fCommandList->RSSetViewports(numViewports, viewports);
|
||||
}
|
||||
|
||||
void GrD3DDirectCommandList::setVertexBuffers(unsigned int startSlot,
|
||||
const GrD3DBuffer* vertexBuffer,
|
||||
size_t vertexStride,
|
||||
const GrD3DBuffer* instanceBuffer,
|
||||
size_t instanceStride) {
|
||||
this->addingWork();
|
||||
this->addResource(vertexBuffer->resource());
|
||||
|
||||
D3D12_VERTEX_BUFFER_VIEW views[2];
|
||||
int numViews = 0;
|
||||
views[numViews].BufferLocation = vertexBuffer->d3dResource()->GetGPUVirtualAddress();
|
||||
views[numViews].SizeInBytes = vertexBuffer->size();
|
||||
views[numViews++].StrideInBytes = vertexStride;
|
||||
if (instanceBuffer) {
|
||||
this->addResource(instanceBuffer->resource());
|
||||
views[numViews].BufferLocation = instanceBuffer->d3dResource()->GetGPUVirtualAddress();
|
||||
views[numViews].SizeInBytes = instanceBuffer->size();
|
||||
views[numViews++].StrideInBytes = instanceStride;
|
||||
}
|
||||
|
||||
fCommandList->IASetVertexBuffers(startSlot, numViews, views);
|
||||
}
|
||||
|
||||
void GrD3DDirectCommandList::setIndexBuffer(const GrD3DBuffer* indexBuffer) {
|
||||
this->addingWork();
|
||||
this->addResource(indexBuffer->resource());
|
||||
|
||||
D3D12_INDEX_BUFFER_VIEW view = {};
|
||||
view.BufferLocation = indexBuffer->d3dResource()->GetGPUVirtualAddress();
|
||||
view.SizeInBytes = indexBuffer->size();
|
||||
view.Format = DXGI_FORMAT_R16_UINT;
|
||||
fCommandList->IASetIndexBuffer(&view);
|
||||
}
|
||||
|
||||
void GrD3DDirectCommandList::clearRenderTargetView(GrD3DRenderTarget* renderTarget,
|
||||
const SkPMColor4f& color,
|
||||
const GrFixedClip& clip) {
|
||||
this->addingWork();
|
||||
this->addResource(renderTarget->resource());
|
||||
fCommandList->ClearRenderTargetView(renderTarget->colorRenderTargetView(),
|
||||
color.vec(),
|
||||
0, NULL); // no cliprects for now
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::unique_ptr<GrD3DCopyCommandList> GrD3DCopyCommandList::Make(ID3D12Device* device) {
|
||||
|
@ -62,9 +62,6 @@ public:
|
||||
const D3D12_TEXTURE_COPY_LOCATION* srcLocation,
|
||||
const D3D12_BOX* srcBox);
|
||||
|
||||
void clearRenderTargetView(GrD3DRenderTarget* renderTarget, const SkPMColor4f& color,
|
||||
const GrFixedClip& clip);
|
||||
|
||||
// Add ref-counted resource that will be tracked and released when this command buffer finishes
|
||||
// execution
|
||||
void addResource(sk_sp<GrManagedResource> resource) {
|
||||
@ -121,7 +118,13 @@ public:
|
||||
void setPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY primitiveTopology);
|
||||
void setScissorRects(unsigned int numRects, const D3D12_RECT* rects);
|
||||
void setViewports(unsigned int numViewports, const D3D12_VIEWPORT* viewports);
|
||||
void setVertexBuffers(unsigned int startSlot,
|
||||
const GrD3DBuffer* vertexBuffer, size_t vertexStride,
|
||||
const GrD3DBuffer* instanceBuffer, size_t instanceStride);
|
||||
void setIndexBuffer(const GrD3DBuffer* indexBuffer);
|
||||
|
||||
void clearRenderTargetView(GrD3DRenderTarget* renderTarget, const SkPMColor4f& color,
|
||||
const GrFixedClip& clip);
|
||||
private:
|
||||
GrD3DDirectCommandList(gr_cp<ID3D12CommandAllocator> allocator,
|
||||
gr_cp<ID3D12GraphicsCommandList> commandList);
|
||||
|
@ -12,9 +12,12 @@
|
||||
#include "src/gpu/GrProgramDesc.h"
|
||||
#include "src/gpu/GrRenderTargetPriv.h"
|
||||
#include "src/gpu/GrStencilSettings.h"
|
||||
#include "src/gpu/d3d/GrD3DBuffer.h"
|
||||
#include "src/gpu/d3d/GrD3DGpu.h"
|
||||
#include "src/gpu/d3d/GrD3DPipelineState.h"
|
||||
#include "src/gpu/d3d/GrD3DPipelineStateBuilder.h"
|
||||
#include "src/gpu/d3d/GrD3DRenderTarget.h"
|
||||
#include "src/gpu/d3d/GrD3DTexture.h"
|
||||
|
||||
GrD3DOpsRenderPass::GrD3DOpsRenderPass(GrD3DGpu* gpu) : fGpu(gpu) {}
|
||||
|
||||
@ -41,6 +44,13 @@ GrD3DOpsRenderPass::~GrD3DOpsRenderPass() {}
|
||||
|
||||
GrGpu* GrD3DOpsRenderPass::gpu() { return fGpu; }
|
||||
|
||||
void GrD3DOpsRenderPass::onBegin() {
|
||||
if (GrLoadOp::kClear == fColorLoadOp) {
|
||||
GrFixedClip clip;
|
||||
fGpu->clear(clip, fClearColor, fRenderTarget);
|
||||
}
|
||||
}
|
||||
|
||||
void set_stencil_ref(GrD3DGpu* gpu, const GrProgramInfo& info) {
|
||||
GrStencilSettings stencilSettings = info.nonGLStencilSettings();
|
||||
if (!stencilSettings.isDisabled()) {
|
||||
@ -139,14 +149,16 @@ bool GrD3DOpsRenderPass::onBindPipeline(const GrProgramInfo& info, const SkRect&
|
||||
fCurrentPipelineBounds.setEmpty();
|
||||
}
|
||||
|
||||
sk_sp<GrD3DPipelineState> pipelineState =
|
||||
fCurrentPipelineState =
|
||||
fGpu->resourceProvider().findOrCreateCompatiblePipelineState(fRenderTarget, info);
|
||||
if (!pipelineState) {
|
||||
if (!fCurrentPipelineState) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pipelineState->setData(fRenderTarget, info);
|
||||
fGpu->currentCommandList()->setPipelineState(std::move(pipelineState));
|
||||
fCurrentPipelineState->setData(fRenderTarget, info);
|
||||
fGpu->currentCommandList()->setPipelineState(fCurrentPipelineState);
|
||||
|
||||
// TODO: bind uniforms (either a new method or in pipelineState->setData())
|
||||
|
||||
set_stencil_ref(fGpu, info);
|
||||
set_blend_factor(fGpu, info);
|
||||
@ -160,11 +172,49 @@ bool GrD3DOpsRenderPass::onBindPipeline(const GrProgramInfo& info, const SkRect&
|
||||
return true;
|
||||
}
|
||||
|
||||
void GrD3DOpsRenderPass::onBegin() {
|
||||
if (GrLoadOp::kClear == fColorLoadOp) {
|
||||
GrFixedClip clip;
|
||||
fGpu->clear(clip, fClearColor, fRenderTarget);
|
||||
void update_resource_state(GrTexture* tex, GrRenderTarget* rt, GrD3DGpu* gpu) {
|
||||
SkASSERT(!tex->isProtected() || (rt->isProtected() && gpu->protectedContext()));
|
||||
GrD3DTexture* d3dTex = static_cast<GrD3DTexture*>(tex);
|
||||
SkASSERT(d3dTex);
|
||||
d3dTex->setResourceState(gpu, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
}
|
||||
|
||||
bool GrD3DOpsRenderPass::onBindTextures(const GrPrimitiveProcessor& primProc,
|
||||
const GrSurfaceProxy* const primProcTextures[],
|
||||
const GrPipeline& pipeline) {
|
||||
SkASSERT(fCurrentPipelineState);
|
||||
|
||||
// update textures to sampled resource state
|
||||
for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
|
||||
update_resource_state(primProcTextures[i]->peekTexture(), fRenderTarget, fGpu);
|
||||
}
|
||||
GrFragmentProcessor::PipelineTextureSamplerRange textureSamplerRange(pipeline);
|
||||
for (auto [sampler, fp] : textureSamplerRange) {
|
||||
update_resource_state(sampler.peekTexture(), fRenderTarget, fGpu);
|
||||
}
|
||||
if (GrTexture* dstTexture = pipeline.peekDstTexture()) {
|
||||
update_resource_state(dstTexture, fRenderTarget, fGpu);
|
||||
}
|
||||
|
||||
// TODO: possibly check for success once we start binding properly
|
||||
fCurrentPipelineState->setAndBindTextures(primProc, primProcTextures, pipeline);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GrD3DOpsRenderPass::onBindBuffers(const GrBuffer* indexBuffer, const GrBuffer* instanceBuffer,
|
||||
const GrBuffer* vertexBuffer,
|
||||
GrPrimitiveRestart primRestart) {
|
||||
SkASSERT(GrPrimitiveRestart::kNo == primRestart);
|
||||
SkASSERT(fCurrentPipelineState);
|
||||
SkASSERT(!fGpu->caps()->usePrimitiveRestart()); // Ignore primitiveRestart parameter.
|
||||
|
||||
GrD3DDirectCommandList* currCmdList = fGpu->currentCommandList();
|
||||
SkASSERT(currCmdList);
|
||||
|
||||
// TODO: do we need a memory barrier here?
|
||||
|
||||
fCurrentPipelineState->bindBuffers(indexBuffer, instanceBuffer, vertexBuffer, currCmdList);
|
||||
}
|
||||
|
||||
void GrD3DOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "include/private/GrTypesPriv.h"
|
||||
|
||||
class GrD3DGpu;
|
||||
class GrD3DPipelineState;
|
||||
|
||||
class GrD3DOpsRenderPass : public GrOpsRenderPass {
|
||||
public:
|
||||
@ -38,11 +39,9 @@ private:
|
||||
bool onBindPipeline(const GrProgramInfo&, const SkRect& drawBounds) override;
|
||||
void onSetScissorRect(const SkIRect&) override {}
|
||||
bool onBindTextures(const GrPrimitiveProcessor&, const GrSurfaceProxy* const primProcTextures[],
|
||||
const GrPipeline&) override {
|
||||
return true;
|
||||
}
|
||||
const GrPipeline&) override;
|
||||
void onBindBuffers(const GrBuffer* indexBuffer, const GrBuffer* instanceBuffer,
|
||||
const GrBuffer* vertexBuffer, GrPrimitiveRestart) override {}
|
||||
const GrBuffer* vertexBuffer, GrPrimitiveRestart) override;
|
||||
void onDraw(int vertexCount, int baseVertex) override {}
|
||||
void onDrawIndexed(int indexCount, int baseIndex, uint16_t minIndexValue,
|
||||
uint16_t maxIndexValue, int baseVertex) override {}
|
||||
@ -56,6 +55,9 @@ private:
|
||||
void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) override {}
|
||||
|
||||
GrD3DGpu* fGpu;
|
||||
|
||||
sk_sp<GrD3DPipelineState> fCurrentPipelineState;
|
||||
|
||||
SkIRect fBounds;
|
||||
SkIRect fCurrentPipelineBounds;
|
||||
|
||||
|
@ -10,8 +10,10 @@
|
||||
#include "include/private/SkTemplates.h"
|
||||
#include "src/gpu/GrProgramInfo.h"
|
||||
#include "src/gpu/GrStencilSettings.h"
|
||||
#include "src/gpu/d3d/GrD3DBuffer.h"
|
||||
#include "src/gpu/d3d/GrD3DGpu.h"
|
||||
#include "src/gpu/d3d/GrD3DRootSignature.h"
|
||||
#include "src/gpu/d3d/GrD3DTexture.h"
|
||||
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
|
||||
#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
|
||||
#include "src/gpu/glsl/GrGLSLXferProcessor.h"
|
||||
@ -20,17 +22,23 @@ GrD3DPipelineState::GrD3DPipelineState(
|
||||
gr_cp<ID3D12PipelineState> pipelineState,
|
||||
const GrGLSLBuiltinUniformHandles& builtinUniformHandles,
|
||||
const UniformInfoArray& uniforms, uint32_t uniformSize,
|
||||
uint32_t numSamplers,
|
||||
std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
|
||||
std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
|
||||
std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors,
|
||||
int fragmentProcessorCnt)
|
||||
int fragmentProcessorCnt,
|
||||
size_t vertexStride,
|
||||
size_t instanceStride)
|
||||
: fPipelineState(std::move(pipelineState))
|
||||
, fBuiltinUniformHandles(builtinUniformHandles)
|
||||
, fGeometryProcessor(std::move(geometryProcessor))
|
||||
, fXferProcessor(std::move(xferProcessor))
|
||||
, fFragmentProcessors(std::move(fragmentProcessors))
|
||||
, fFragmentProcessorCnt(fragmentProcessorCnt)
|
||||
, fDataManager(uniforms, uniformSize) {}
|
||||
, fDataManager(uniforms, uniformSize)
|
||||
, fNumSamplers(numSamplers)
|
||||
, fVertexStride(vertexStride)
|
||||
, fInstanceStride(instanceStride) {}
|
||||
|
||||
void GrD3DPipelineState::setData(const GrRenderTarget* renderTarget,
|
||||
const GrProgramInfo& programInfo) {
|
||||
@ -55,7 +63,6 @@ void GrD3DPipelineState::setData(const GrRenderTarget* renderTarget,
|
||||
}
|
||||
|
||||
void GrD3DPipelineState::setRenderTargetState(const GrRenderTarget* rt, GrSurfaceOrigin origin) {
|
||||
|
||||
// Load the RT height uniform if it is needed to y-flip gl_FragCoord.
|
||||
if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
|
||||
fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
|
||||
@ -75,3 +82,65 @@ void GrD3DPipelineState::setRenderTargetState(const GrRenderTarget* rt, GrSurfac
|
||||
fDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
|
||||
}
|
||||
}
|
||||
|
||||
void GrD3DPipelineState::setAndBindTextures(const GrPrimitiveProcessor& primProc,
|
||||
const GrSurfaceProxy* const primProcTextures[],
|
||||
const GrPipeline& pipeline) {
|
||||
SkASSERT(primProcTextures || !primProc.numTextureSamplers());
|
||||
|
||||
struct SamplerBindings {
|
||||
GrSamplerState fState;
|
||||
GrD3DTexture* fTexture;
|
||||
};
|
||||
SkAutoSTMalloc<8, SamplerBindings> samplerBindings(fNumSamplers);
|
||||
int currTextureBinding = 0;
|
||||
|
||||
for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
|
||||
SkASSERT(primProcTextures[i]->asTextureProxy());
|
||||
const auto& sampler = primProc.textureSampler(i);
|
||||
auto texture = static_cast<GrD3DTexture*>(primProcTextures[i]->peekTexture());
|
||||
samplerBindings[currTextureBinding++] = { sampler.samplerState(), texture };
|
||||
}
|
||||
|
||||
GrFragmentProcessor::CIter fpIter(pipeline);
|
||||
GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
|
||||
for (; fpIter && glslIter; ++fpIter, ++glslIter) {
|
||||
for (int i = 0; i < fpIter->numTextureSamplers(); ++i) {
|
||||
const auto& sampler = fpIter->textureSampler(i);
|
||||
samplerBindings[currTextureBinding++] =
|
||||
{ sampler.samplerState(), static_cast<GrD3DTexture*>(sampler.peekTexture()) };
|
||||
}
|
||||
}
|
||||
SkASSERT(!fpIter && !glslIter);
|
||||
|
||||
if (GrTexture* dstTexture = pipeline.peekDstTexture()) {
|
||||
samplerBindings[currTextureBinding++] = {
|
||||
GrSamplerState::Filter::kNearest, static_cast<GrD3DTexture*>(dstTexture) };
|
||||
}
|
||||
|
||||
// TODO: bind descriptors
|
||||
SkASSERT(fNumSamplers == currTextureBinding);
|
||||
}
|
||||
|
||||
void GrD3DPipelineState::bindBuffers(const GrBuffer* indexBuffer, const GrBuffer* instanceBuffer,
|
||||
const GrBuffer* vertexBuffer,
|
||||
GrD3DDirectCommandList* commandList) {
|
||||
// Here our vertex and instance inputs need to match the same 0-based bindings they were
|
||||
// assigned in the PipelineState. That is, vertex first (if any) followed by instance.
|
||||
if (auto* d3dVertexBuffer = static_cast<const GrD3DBuffer*>(vertexBuffer)) {
|
||||
SkASSERT(!d3dVertexBuffer->isCpuBuffer());
|
||||
SkASSERT(!d3dVertexBuffer->isMapped());
|
||||
auto* d3dInstanceBuffer = static_cast<const GrD3DBuffer*>(instanceBuffer);
|
||||
if (d3dInstanceBuffer) {
|
||||
SkASSERT(!d3dInstanceBuffer->isCpuBuffer());
|
||||
SkASSERT(!d3dInstanceBuffer->isMapped());
|
||||
}
|
||||
commandList->setVertexBuffers(0, d3dVertexBuffer, fVertexStride,
|
||||
d3dInstanceBuffer, fInstanceStride);
|
||||
}
|
||||
if (auto* d3dIndexBuffer = static_cast<const GrD3DBuffer*>(indexBuffer)) {
|
||||
SkASSERT(!d3dIndexBuffer->isCpuBuffer());
|
||||
SkASSERT(!d3dIndexBuffer->isMapped());
|
||||
commandList->setIndexBuffer(d3dIndexBuffer);
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "src/gpu/d3d/GrD3DPipelineStateDataManager.h"
|
||||
#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
|
||||
|
||||
class GrD3DDirectCommandList;
|
||||
class GrD3DGpu;
|
||||
class GrD3DRootSignature;
|
||||
class GrProgramInfo;
|
||||
@ -27,10 +28,13 @@ public:
|
||||
const GrGLSLBuiltinUniformHandles& builtinUniformHandles,
|
||||
const UniformInfoArray& uniforms,
|
||||
uint32_t uniformSize,
|
||||
uint32_t numSamplers,
|
||||
std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
|
||||
std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
|
||||
std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragProcessors,
|
||||
int fragmentProcessorCnt);
|
||||
int fragmentProcessorCnt,
|
||||
size_t vertexStride,
|
||||
size_t instanceStride);
|
||||
|
||||
#ifdef SK_TRACE_MANAGED_RESOURCES
|
||||
/** Output a human-readable dump of this resource's information
|
||||
@ -48,6 +52,13 @@ public:
|
||||
|
||||
void setData(const GrRenderTarget* renderTarget, const GrProgramInfo& programInfo);
|
||||
|
||||
void setAndBindTextures(const GrPrimitiveProcessor& primProc,
|
||||
const GrSurfaceProxy* const primProcTextures[],
|
||||
const GrPipeline& pipeline);
|
||||
|
||||
void bindBuffers(const GrBuffer* indexBuffer, const GrBuffer* instanceBuffer,
|
||||
const GrBuffer* vertexBuffer, GrD3DDirectCommandList* commandList);
|
||||
|
||||
private:
|
||||
/**
|
||||
* We use the RT's size and origin to adjust from Skia device space to d3d normalized device
|
||||
@ -101,6 +112,10 @@ private:
|
||||
int fFragmentProcessorCnt;
|
||||
|
||||
GrD3DPipelineStateDataManager fDataManager;
|
||||
|
||||
int fNumSamplers;
|
||||
size_t fVertexStride;
|
||||
size_t fInstanceStride;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -536,7 +536,8 @@ sk_sp<GrD3DPipelineState> GrD3DPipelineStateBuilder::finalize() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (this->primitiveProcessor().willUseGeoShader()) {
|
||||
const GrPrimitiveProcessor& primProc = this->primitiveProcessor();
|
||||
if (primProc.willUseGeoShader()) {
|
||||
this->compileD3DProgram(SkSL::Program::kGeometry_Kind, fGS.fCompilerString, settings,
|
||||
&geometryShader, &geomInputs);
|
||||
if (!geometryShader.get()) {
|
||||
@ -560,8 +561,11 @@ sk_sp<GrD3DPipelineState> GrD3DPipelineStateBuilder::finalize() {
|
||||
fUniformHandles,
|
||||
fUniformHandler.fUniforms,
|
||||
fUniformHandler.fCurrentUBOOffset,
|
||||
fUniformHandler.fSamplers.count(),
|
||||
std::move(fGeometryProcessor),
|
||||
std::move(fXferProcessor),
|
||||
std::move(fFragmentProcessors),
|
||||
fFragmentProcessorCnt));
|
||||
fFragmentProcessorCnt,
|
||||
primProc.vertexStride(),
|
||||
primProc.instanceStride()));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user